i18n-0.7.0/0000755000004100000410000000000012461054500012322 5ustar www-datawww-datai18n-0.7.0/MIT-LICENSE0000644000004100000410000000204512461054500013757 0ustar www-datawww-dataCopyright (c) 2008 The Ruby I18n team Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.i18n-0.7.0/lib/0000755000004100000410000000000012461054500013070 5ustar www-datawww-datai18n-0.7.0/lib/i18n/0000755000004100000410000000000012461054500013647 5ustar www-datawww-datai18n-0.7.0/lib/i18n/tests.rb0000644000004100000410000000070012461054500015333 0ustar www-datawww-datamodule I18n module Tests autoload :Basics, 'i18n/tests/basics' autoload :Defaults, 'i18n/tests/defaults' autoload :Interpolation, 'i18n/tests/interpolation' autoload :Link, 'i18n/tests/link' autoload :Localization, 'i18n/tests/localization' autoload :Lookup, 'i18n/tests/lookup' autoload :Pluralization, 'i18n/tests/pluralization' autoload :Procs, 'i18n/tests/procs' end end i18n-0.7.0/lib/i18n/tests/0000755000004100000410000000000012461054500015011 5ustar www-datawww-datai18n-0.7.0/lib/i18n/tests/lookup.rb0000644000004100000410000000545512461054500016660 0ustar www-datawww-data# encoding: utf-8 module I18n module Tests module Lookup def setup super I18n.backend.store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' }, :falsy => false, :truthy => true, :string => "a", :array => %w(a b c), :hash => { "a" => "b" }) end test "lookup: it returns a string" do assert_equal("a", I18n.t(:string)) end test "lookup: it returns hash" do assert_equal({ :a => "b" }, I18n.t(:hash)) end test "lookup: it returns an array" do assert_equal(%w(a b c), I18n.t(:array)) end test "lookup: it returns a native true" do assert I18n.t(:truthy) === true end test "lookup: it returns a native false" do assert I18n.t(:falsy) === false end test "lookup: given a missing key, no default and no raise option it returns an error message" do assert_equal "translation missing: en.missing", I18n.t(:missing) end test "lookup: given a missing key, no default and the raise option it raises MissingTranslationData" do assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) } end test "lookup: does not raise an exception if no translation data is present for the given locale" do assert_nothing_raised { I18n.t(:foo, :locale => :xx) } end test "lookup: does not modify the options hash" do options = {} assert_equal "a", I18n.t(:string, options) assert_equal({}, options) assert_nothing_raised { I18n.t(:string, options.freeze) } end test "lookup: given an array of keys it translates all of them" do assert_equal %w(bar baz), I18n.t([:bar, :baz], :scope => [:foo]) end test "lookup: using a custom scope separator" do # data must have been stored using the custom separator when using the ActiveRecord backend I18n.backend.store_translations(:en, { :foo => { :bar => 'bar' } }, { :separator => '|' }) assert_equal 'bar', I18n.t('foo|bar', :separator => '|') end # In fact it probably *should* fail but Rails currently relies on using the default locale instead. # So we'll stick to this for now until we get it fixed in Rails. test "lookup: given nil as a locale it does not raise but use the default locale" do # assert_raise(I18n::InvalidLocale) { I18n.t(:bar, :locale => nil) } assert_nothing_raised { I18n.t(:bar, :locale => nil) } end test "lookup: a resulting String is not frozen" do assert !I18n.t(:string).frozen? end test "lookup: a resulting Array is not frozen" do assert !I18n.t(:array).frozen? end test "lookup: a resulting Hash is not frozen" do assert !I18n.t(:hash).frozen? end end end end i18n-0.7.0/lib/i18n/tests/localization.rb0000644000004100000410000000111312461054500020022 0ustar www-datawww-datamodule I18n module Tests module Localization autoload :Date, 'i18n/tests/localization/date' autoload :DateTime, 'i18n/tests/localization/date_time' autoload :Time, 'i18n/tests/localization/time' autoload :Procs, 'i18n/tests/localization/procs' def self.included(base) base.class_eval do include I18n::Tests::Localization::Date include I18n::Tests::Localization::DateTime include I18n::Tests::Localization::Procs include I18n::Tests::Localization::Time end end end end endi18n-0.7.0/lib/i18n/tests/interpolation.rb0000644000004100000410000001357012461054500020233 0ustar www-datawww-data# encoding: utf-8 module I18n module Tests module Interpolation # 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. # test "interpolation: given no values it does not alter the string" do assert_equal 'Hi %{name}!', interpolate(:default => 'Hi %{name}!') end test "interpolation: given values it interpolates them into the string" do assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => 'David') end test "interpolation: given a nil value it still interpolates it into the string" do assert_equal 'Hi !', interpolate(:default => 'Hi %{name}!', :name => nil) end 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 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 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 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 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 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 test "interpolation: given the value is in utf-8 it still works" do assert_equal 'Hi ゆきひろ!', interpolate(:default => 'Hi %{name}!', :name => 'ゆきひろ') end test "interpolation: given the translation and the value are in utf-8 it still works" do assert_equal 'こんにちは、ゆきひろさん!', interpolate(:default => 'こんにちは、%{name}さん!', :name => 'ゆきひろ') end if Object.const_defined?(:Encoding) 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 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 test "interpolation: 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 "interpolation: UTF8 strings in the backend are still returned as UTF8 with ASCII interpolation" 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 "interpolation: UTF8 strings in the backend are still returned as UTF8 even with numbers interpolation" 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 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 protected def capture(stream) begin stream = stream.to_s eval "$#{stream} = StringIO.new" yield result = eval("$#{stream}").string ensure eval("$#{stream} = #{stream.upcase}") end result end def euc_jp(string) string.encode!(Encoding::EUC_JP) end def interpolate(*args) options = args.last.is_a?(Hash) ? args.pop : {} key = args.pop I18n.backend.translate('en', key, options) end end end end i18n-0.7.0/lib/i18n/tests/basics.rb0000644000004100000410000000421512461054500016604 0ustar www-datawww-datamodule I18n module Tests module Basics def teardown I18n.available_locales = nil end test "available_locales returns the locales stored to the backend by default" do I18n.backend.store_translations('de', :foo => 'bar') I18n.backend.store_translations('en', :foo => 'foo') assert I18n.available_locales.include?(:de) assert I18n.available_locales.include?(:en) end test "available_locales can be set to something else independently from the actual locale data" do I18n.backend.store_translations('de', :foo => 'bar') I18n.backend.store_translations('en', :foo => 'foo') I18n.available_locales = :foo assert_equal [:foo], I18n.available_locales I18n.available_locales = [:foo, 'bar'] assert_equal [:foo, :bar], I18n.available_locales I18n.available_locales = nil assert I18n.available_locales.include?(:de) assert I18n.available_locales.include?(:en) end test "available_locales memoizes when set explicitely" do I18n.backend.expects(:available_locales).never I18n.available_locales = [:foo] I18n.backend.store_translations('de', :bar => 'baz') I18n.reload! assert_equal [:foo], I18n.available_locales end test "available_locales delegates to the backend when not set explicitely" do I18n.backend.expects(:available_locales).twice assert_equal I18n.available_locales, I18n.available_locales end test "exists? is implemented by the backend" do I18n.backend.store_translations(:foo, :bar => 'baz') assert I18n.exists?(:bar, :foo) end test "storing a nil value as a translation removes it from the available locale data" do I18n.backend.store_translations(:en, :to_be_deleted => 'bar') assert_equal 'bar', I18n.t(:to_be_deleted, :default => 'baz') I18n.cache_store.clear if I18n.respond_to?(:cache_store) && I18n.cache_store I18n.backend.store_translations(:en, :to_be_deleted => nil) assert_equal 'baz', I18n.t(:to_be_deleted, :default => 'baz') end end end end i18n-0.7.0/lib/i18n/tests/link.rb0000644000004100000410000000422712461054500016300 0ustar www-datawww-data# encoding: utf-8 module I18n module Tests module Link test "linked lookup: if a key resolves to a symbol it looks up the symbol" do I18n.backend.store_translations 'en', { :link => :linked, :linked => 'linked' } assert_equal 'linked', I18n.backend.translate('en', :link) end test "linked lookup: if a key resolves to a dot-separated symbol it looks up the symbol" do I18n.backend.store_translations 'en', { :link => :"foo.linked", :foo => { :linked => 'linked' } } assert_equal('linked', I18n.backend.translate('en', :link)) end test "linked lookup: if a dot-separated key resolves to a symbol it looks up the symbol" do I18n.backend.store_translations 'en', { :foo => { :link => :linked }, :linked => 'linked' } assert_equal('linked', I18n.backend.translate('en', :'foo.link')) end test "linked lookup: if a dot-separated key resolves to a dot-separated symbol it looks up the symbol" do I18n.backend.store_translations 'en', { :foo => { :link => :"bar.linked" }, :bar => { :linked => 'linked' } } assert_equal('linked', I18n.backend.translate('en', :'foo.link')) end test "linked lookup: links always refer to the absolute key" do I18n.backend.store_translations 'en', { :foo => { :link => :linked, :linked => 'linked in foo' }, :linked => 'linked absolutely' } assert_equal 'linked absolutely', I18n.backend.translate('en', :link, :scope => :foo) end test "linked lookup: a link can resolve to a namespace in the middle of a dot-separated key" do I18n.backend.store_translations 'en', { :activemodel => { :errors => { :messages => { :blank => "can't be blank" } } }, :activerecord => { :errors => { :messages => :"activemodel.errors.messages" } } } assert_equal "can't be blank", I18n.t(:"activerecord.errors.messages.blank") assert_equal "can't be blank", I18n.t(:"activerecord.errors.messages.blank") end end end end i18n-0.7.0/lib/i18n/tests/defaults.rb0000644000004100000410000000301112461054500017140 0ustar www-datawww-data# encoding: utf-8 module I18n module Tests module Defaults def setup super I18n.backend.store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' }) end test "defaults: given nil as a key it returns the given default" do assert_equal 'default', I18n.t(nil, :default => 'default') end test "defaults: given a symbol as a default it translates the symbol" do assert_equal 'bar', I18n.t(nil, :default => :'foo.bar') end test "defaults: given a symbol as a default and a scope it stays inside the scope when looking up the symbol" do assert_equal 'bar', I18n.t(:missing, :default => :bar, :scope => :foo) end test "defaults: given an array as a default it returns the first match" do assert_equal 'bar', I18n.t(:does_not_exist, :default => [:does_not_exist_2, :'foo.bar']) end test "defaults: given an array of missing keys it raises a MissingTranslationData exception" do assert_raise I18n::MissingTranslationData do I18n.t(:does_not_exist, :default => [:does_not_exist_2, :does_not_exist_3], :raise => true) end end test "defaults: using a custom scope separator" do # data must have been stored using the custom separator when using the ActiveRecord backend I18n.backend.store_translations(:en, { :foo => { :bar => 'bar' } }, { :separator => '|' }) assert_equal 'bar', I18n.t(nil, :default => :'foo|bar', :separator => '|') end end end end i18n-0.7.0/lib/i18n/tests/pluralization.rb0000644000004100000410000000252012461054500020232 0ustar www-datawww-data# encoding: utf-8 module I18n module Tests module Pluralization test "pluralization: given 0 it returns the :zero translation if it is defined" do assert_equal 'zero', I18n.t(:default => { :zero => 'zero' }, :count => 0) end test "pluralization: given 0 it returns the :other translation if :zero is not defined" do assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 0) end test "pluralization: given 1 it returns the singular translation" do assert_equal 'bar', I18n.t(:default => { :one => 'bar' }, :count => 1) end test "pluralization: given 2 it returns the :other translation" do assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 2) end test "pluralization: given 3 it returns the :other translation" do assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 3) end test "pluralization: given nil it returns the whole entry" do assert_equal({ :one => 'bar' }, I18n.t(:default => { :one => 'bar' }, :count => nil)) end test "pluralization: given incomplete pluralization data it raises I18n::InvalidPluralizationData" do assert_raise(I18n::InvalidPluralizationData) { I18n.t(:default => { :one => 'bar' }, :count => 2) } end end end end i18n-0.7.0/lib/i18n/tests/localization/0000755000004100000410000000000012461054500017501 5ustar www-datawww-datai18n-0.7.0/lib/i18n/tests/localization/date_time.rb0000644000004100000410000000636412461054500021772 0ustar www-datawww-data# encoding: utf-8 module I18n module Tests module Localization module DateTime def setup super setup_datetime_translations @datetime = ::DateTime.new(2008, 3, 1, 6) @other_datetime = ::DateTime.new(2008, 3, 1, 18) end test "localize DateTime: given the short format it uses it" do # TODO should be Mrz, shouldn't it? assert_equal '01. Mar 06:00', I18n.l(@datetime, :format => :short, :locale => :de) end test "localize DateTime: given the long format it uses it" do assert_equal '01. März 2008 06:00', I18n.l(@datetime, :format => :long, :locale => :de) end test "localize DateTime: given the default format it uses it" do # TODO should be Mrz, shouldn't it? assert_equal 'Sa, 01. Mar 2008 06:00:00 +0000', I18n.l(@datetime, :format => :default, :locale => :de) end test "localize DateTime: given a day name format it returns the correct day name" do assert_equal 'Samstag', I18n.l(@datetime, :format => '%A', :locale => :de) end test "localize DateTime: given an abbreviated day name format it returns the correct abbreviated day name" do assert_equal 'Sa', I18n.l(@datetime, :format => '%a', :locale => :de) end test "localize DateTime: given a month name format it returns the correct month name" do assert_equal 'März', I18n.l(@datetime, :format => '%B', :locale => :de) end test "localize DateTime: given an abbreviated month name format it returns the correct abbreviated month name" do # TODO should be Mrz, shouldn't it? assert_equal 'Mar', I18n.l(@datetime, :format => '%b', :locale => :de) end test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator" do assert_equal 'AM', I18n.l(@datetime, :format => '%p', :locale => :de) assert_equal 'PM', I18n.l(@other_datetime, :format => '%p', :locale => :de) end test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator in downcase" do assert_equal 'am', I18n.l(@datetime, :format => '%P', :locale => :de) assert_equal 'pm', I18n.l(@other_datetime, :format => '%P', :locale => :de) end test "localize DateTime: given an unknown format it does not fail" do assert_nothing_raised { I18n.l(@datetime, :format => '%x') } end test "localize DateTime: given a format is missing it raises I18n::MissingTranslationData" do assert_raise(I18n::MissingTranslationData) { I18n.l(@datetime, :format => :missing) } end protected def setup_datetime_translations # time translations might have been set up in Tests::Api::Localization::Time I18n.backend.store_translations :de, { :time => { :formats => { :default => "%a, %d. %b %Y %H:%M:%S %z", :short => "%d. %b %H:%M", :long => "%d. %B %Y %H:%M" }, :am => 'am', :pm => 'pm' } } end end end end end i18n-0.7.0/lib/i18n/tests/localization/time.rb0000644000004100000410000000613412461054500020770 0ustar www-datawww-data# encoding: utf-8 module I18n module Tests module Localization module Time def setup super setup_time_translations @time = ::Time.utc(2008, 3, 1, 6, 0) @other_time = ::Time.utc(2008, 3, 1, 18, 0) end test "localize Time: given the short format it uses it" do # TODO should be Mrz, shouldn't it? assert_equal '01. Mar 06:00', I18n.l(@time, :format => :short, :locale => :de) end test "localize Time: given the long format it uses it" do assert_equal '01. März 2008 06:00', I18n.l(@time, :format => :long, :locale => :de) end # TODO Seems to break on Windows because ENV['TZ'] is ignored. What's a better way to do this? # def test_localize_given_the_default_format_it_uses_it # assert_equal 'Sa, 01. Mar 2008 06:00:00 +0000', I18n.l(@time, :format => :default, :locale => :de) # end test "localize Time: given a day name format it returns the correct day name" do assert_equal 'Samstag', I18n.l(@time, :format => '%A', :locale => :de) end test "localize Time: given an abbreviated day name format it returns the correct abbreviated day name" do assert_equal 'Sa', I18n.l(@time, :format => '%a', :locale => :de) end test "localize Time: given a month name format it returns the correct month name" do assert_equal 'März', I18n.l(@time, :format => '%B', :locale => :de) end test "localize Time: given an abbreviated month name format it returns the correct abbreviated month name" do # TODO should be Mrz, shouldn't it? assert_equal 'Mar', I18n.l(@time, :format => '%b', :locale => :de) end test "localize Time: given a meridian indicator format it returns the correct meridian indicator" do assert_equal 'AM', I18n.l(@time, :format => '%p', :locale => :de) assert_equal 'PM', I18n.l(@other_time, :format => '%p', :locale => :de) end test "localize Time: given a meridian indicator format it returns the correct meridian indicator in upcase" do assert_equal 'am', I18n.l(@time, :format => '%P', :locale => :de) assert_equal 'pm', I18n.l(@other_time, :format => '%P', :locale => :de) end test "localize Time: given an unknown format it does not fail" do assert_nothing_raised { I18n.l(@time, :format => '%x') } end test "localize Time: given a format is missing it raises I18n::MissingTranslationData" do assert_raise(I18n::MissingTranslationData) { I18n.l(@time, :format => :missing) } end protected def setup_time_translations I18n.backend.store_translations :de, { :time => { :formats => { :default => "%a, %d. %b %Y %H:%M:%S %z", :short => "%d. %b %H:%M", :long => "%d. %B %Y %H:%M", }, :am => 'am', :pm => 'pm' } } end end end end end i18n-0.7.0/lib/i18n/tests/localization/date.rb0000644000004100000410000000707512461054500020754 0ustar www-datawww-data# encoding: utf-8 module I18n module Tests module Localization module Date def setup super setup_date_translations @date = ::Date.new(2008, 3, 1) end test "localize Date: given the short format it uses it" do # TODO should be Mrz, shouldn't it? assert_equal '01. Mar', I18n.l(@date, :format => :short, :locale => :de) end test "localize Date: given the long format it uses it" do assert_equal '01. März 2008', I18n.l(@date, :format => :long, :locale => :de) end test "localize Date: given the default format it uses it" do assert_equal '01.03.2008', I18n.l(@date, :format => :default, :locale => :de) end test "localize Date: given a day name format it returns the correct day name" do assert_equal 'Samstag', I18n.l(@date, :format => '%A', :locale => :de) end test "localize Date: given an abbreviated day name format it returns the correct abbreviated day name" do assert_equal 'Sa', I18n.l(@date, :format => '%a', :locale => :de) end test "localize Date: given a month name format it returns the correct month name" do assert_equal 'März', I18n.l(@date, :format => '%B', :locale => :de) end test "localize Date: given an abbreviated month name format it returns the correct abbreviated month name" do # TODO should be Mrz, shouldn't it? assert_equal 'Mar', I18n.l(@date, :format => '%b', :locale => :de) end test "localize Date: given an unknown format it does not fail" do assert_nothing_raised { I18n.l(@date, :format => '%x') } end test "localize Date: does not modify the options hash" do options = { :format => '%b', :locale => :de } assert_equal 'Mar', I18n.l(@date, options) assert_equal({ :format => '%b', :locale => :de }, options) assert_nothing_raised { I18n.l(@date, options.freeze) } end test "localize Date: given nil it raises I18n::ArgumentError" do assert_raise(I18n::ArgumentError) { I18n.l(nil) } end test "localize Date: given a plain Object it raises I18n::ArgumentError" do assert_raise(I18n::ArgumentError) { I18n.l(Object.new) } end test "localize Date: given a format is missing it raises I18n::MissingTranslationData" do assert_raise(I18n::MissingTranslationData) { I18n.l(@date, :format => :missing) } end test "localize Date: it does not alter the format string" do assert_equal '01. Februar 2009', I18n.l(::Date.parse('2009-02-01'), :format => :long, :locale => :de) assert_equal '01. Oktober 2009', I18n.l(::Date.parse('2009-10-01'), :format => :long, :locale => :de) end protected def setup_date_translations I18n.backend.store_translations :de, { :date => { :formats => { :default => "%d.%m.%Y", :short => "%d. %b", :long => "%d. %B %Y", }, :day_names => %w(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag), :abbr_day_names => %w(So Mo Di Mi Do Fr Sa), :month_names => %w(Januar Februar März April Mai Juni Juli August September Oktober November Dezember).unshift(nil), :abbr_month_names => %w(Jan Feb Mar Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil) } } end end end end end i18n-0.7.0/lib/i18n/tests/localization/procs.rb0000644000004100000410000001250212461054500021154 0ustar www-datawww-data# encoding: utf-8 module I18n module Tests module Localization module Procs test "localize: using day names from lambdas" do setup_time_proc_translations time = ::Time.utc(2008, 3, 1, 6, 0) assert_match(/Суббота/, I18n.l(time, :format => "%A, %d %B", :locale => :ru)) assert_match(/суббота/, I18n.l(time, :format => "%d %B (%A)", :locale => :ru)) end test "localize: using month names from lambdas" do setup_time_proc_translations time = ::Time.utc(2008, 3, 1, 6, 0) assert_match(/марта/, I18n.l(time, :format => "%d %B %Y", :locale => :ru)) assert_match(/Март /, I18n.l(time, :format => "%B %Y", :locale => :ru)) end test "localize: using abbreviated day names from lambdas" do setup_time_proc_translations time = ::Time.utc(2008, 3, 1, 6, 0) assert_match(/марта/, I18n.l(time, :format => "%d %b %Y", :locale => :ru)) assert_match(/март /, I18n.l(time, :format => "%b %Y", :locale => :ru)) end test "localize Date: given a format that resolves to a Proc it calls the Proc with the object" do setup_time_proc_translations date = ::Date.new(2008, 3, 1) assert_equal '[Sat, 01 Mar 2008, {}]', I18n.l(date, :format => :proc, :locale => :ru) end test "localize Date: given a format that resolves to a Proc it calls the Proc with the object and extra options" do setup_time_proc_translations date = ::Date.new(2008, 3, 1) assert_equal '[Sat, 01 Mar 2008, {:foo=>"foo"}]', I18n.l(date, :format => :proc, :foo => 'foo', :locale => :ru) end test "localize DateTime: given a format that resolves to a Proc it calls the Proc with the object" do setup_time_proc_translations datetime = ::DateTime.new(2008, 3, 1, 6) assert_equal '[Sat, 01 Mar 2008 06:00:00 +00:00, {}]', I18n.l(datetime, :format => :proc, :locale => :ru) end test "localize DateTime: given a format that resolves to a Proc it calls the Proc with the object and extra options" do setup_time_proc_translations datetime = ::DateTime.new(2008, 3, 1, 6) assert_equal '[Sat, 01 Mar 2008 06:00:00 +00:00, {:foo=>"foo"}]', I18n.l(datetime, :format => :proc, :foo => 'foo', :locale => :ru) end test "localize Time: given a format that resolves to a Proc it calls the Proc with the object" do setup_time_proc_translations time = ::Time.utc(2008, 3, 1, 6, 0) assert_equal inspect_args([time, {}]), I18n.l(time, :format => :proc, :locale => :ru) end test "localize Time: given a format that resolves to a Proc it calls the Proc with the object and extra options" do setup_time_proc_translations time = ::Time.utc(2008, 3, 1, 6, 0) options = { :foo => 'foo' } assert_equal inspect_args([time, options]), I18n.l(time, options.merge(:format => :proc, :locale => :ru)) end protected def inspect_args(args) args = args.map do |arg| case arg when ::Time, ::DateTime arg.strftime('%a, %d %b %Y %H:%M:%S %Z').sub('+0000', '+00:00') when ::Date arg.strftime('%a, %d %b %Y') when Hash arg.delete(:fallback) arg.inspect else arg.inspect end end "[#{args.join(', ')}]" end def setup_time_proc_translations I18n.backend.store_translations :ru, { :time => { :formats => { :proc => lambda { |*args| inspect_args(args) } } }, :date => { :formats => { :proc => lambda { |*args| inspect_args(args) } }, :'day_names' => lambda { |key, options| (options[:format] =~ /^%A/) ? %w(Воскресенье Понедельник Вторник Среда Четверг Пятница Суббота) : %w(воскресенье понедельник вторник среда четверг пятница суббота) }, :'month_names' => lambda { |key, options| (options[:format] =~ /(%d|%e)(\s*)?(%B)/) ? %w(января февраля марта апреля мая июня июля августа сентября октября ноября декабря).unshift(nil) : %w(Январь Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь).unshift(nil) }, :'abbr_month_names' => lambda { |key, options| (options[:format] =~ /(%d|%e)(\s*)(%b)/) ? %w(янв. февр. марта апр. мая июня июля авг. сент. окт. нояб. дек.).unshift(nil) : %w(янв. февр. март апр. май июнь июль авг. сент. окт. нояб. дек.).unshift(nil) }, } } end end end end end i18n-0.7.0/lib/i18n/tests/procs.rb0000644000004100000410000000525212461054500016470 0ustar www-datawww-data# encoding: utf-8 module I18n module Tests module Procs test "lookup: given a translation is a proc it calls the proc with the key and interpolation values" do I18n.backend.store_translations(:en, :a_lambda => lambda { |*args| filter_args(*args) }) assert_equal '[:a_lambda, {:foo=>"foo"}]', I18n.t(:a_lambda, :foo => 'foo') end test "defaults: given a default is a Proc it calls it with the key and interpolation values" do proc = lambda { |*args| filter_args(*args) } assert_equal '[nil, {:foo=>"foo"}]', I18n.t(nil, :default => proc, :foo => 'foo') end test "defaults: given a default is a key that resolves to a Proc it calls it with the key and interpolation values" do I18n.backend.store_translations(:en, :a_lambda => lambda { |*args| filter_args(*args) }) assert_equal '[:a_lambda, {:foo=>"foo"}]', I18n.t(nil, :default => :a_lambda, :foo => 'foo') assert_equal '[:a_lambda, {:foo=>"foo"}]', I18n.t(nil, :default => [nil, :a_lambda], :foo => 'foo') end test "interpolation: given an interpolation value is a lambda it calls it with key and values before interpolating it" do proc = lambda { |*args| filter_args(*args) } assert_match %r(\[\{:foo=>#\}\]), I18n.t(nil, :default => '%{foo}', :foo => proc) end test "interpolation: given a key resolves to a Proc that returns a string then interpolation still works" do proc = lambda { |*args| "%{foo}: " + filter_args(*args) } assert_equal 'foo: [nil, {:foo=>"foo"}]', I18n.t(nil, :default => proc, :foo => 'foo') end test "pluralization: given a key resolves to a Proc that returns valid data then pluralization still works" do proc = lambda { |*args| { :zero => 'zero', :one => 'one', :other => 'other' } } assert_equal 'zero', I18n.t(:default => proc, :count => 0) assert_equal 'one', I18n.t(:default => proc, :count => 1) assert_equal 'other', I18n.t(:default => proc, :count => 2) end test "lookup: given the option :resolve => false was passed it does not resolve proc translations" do I18n.backend.store_translations(:en, :a_lambda => lambda { |*args| filter_args(*args) }) assert_equal Proc, I18n.t(:a_lambda, :resolve => false).class end test "lookup: given the option :resolve => false was passed it does not resolve proc default" do assert_equal Proc, I18n.t(nil, :default => lambda { |*args| filter_args(*args) }, :resolve => false).class end protected def filter_args(*args) args.map {|arg| arg.delete(:fallback) if arg.is_a?(Hash) ; arg }.inspect end end end end i18n-0.7.0/lib/i18n/core_ext/0000755000004100000410000000000012461054500015457 5ustar www-datawww-datai18n-0.7.0/lib/i18n/core_ext/hash.rb0000644000004100000410000000142512461054500016731 0ustar www-datawww-dataclass Hash def slice(*keep_keys) h = {} keep_keys.each { |key| h[key] = fetch(key) } h end unless Hash.method_defined?(:slice) def except(*less_keys) slice(*keys - less_keys) end unless Hash.method_defined?(:except) def deep_symbolize_keys inject({}) { |result, (key, value)| value = value.deep_symbolize_keys if value.is_a?(Hash) result[(key.to_sym rescue key) || key] = value result } end unless Hash.method_defined?(:deep_symbolize_keys) # deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809 MERGER = proc do |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2 end def deep_merge!(data) merge!(data, &MERGER) end unless Hash.method_defined?(:deep_merge!) end i18n-0.7.0/lib/i18n/core_ext/kernel/0000755000004100000410000000000012461054500016737 5ustar www-datawww-datai18n-0.7.0/lib/i18n/core_ext/kernel/suppress_warnings.rb0000644000004100000410000000022612461054500023060 0ustar www-datawww-datamodule Kernel def suppress_warnings original_verbosity, $VERBOSE = $VERBOSE, nil yield ensure $VERBOSE = original_verbosity end end i18n-0.7.0/lib/i18n/core_ext/string/0000755000004100000410000000000012461054500016765 5ustar www-datawww-datai18n-0.7.0/lib/i18n/core_ext/string/interpolate.rb0000644000004100000410000000075512461054500021647 0ustar www-datawww-data# This file used to backport the Ruby 1.9 String interpolation syntax to Ruby 1.8. # # Since I18n has dropped support to Ruby 1.8, this file is not required anymore, # however, Rails 3.2 still requires it directly: # # https://github.com/rails/rails/blob/3-2-stable/activesupport/lib/active_support/core_ext/string/interpolation.rb#L2 # # So we can't just drop the file entirely, which would then break Rails users # under Ruby 1.9. This file can be removed once Rails 3.2 support is dropped. i18n-0.7.0/lib/i18n/gettext/0000755000004100000410000000000012461054500015333 5ustar www-datawww-datai18n-0.7.0/lib/i18n/gettext/helpers.rb0000644000004100000410000000414112461054500017322 0ustar www-datawww-datarequire 'i18n/gettext' module I18n module Gettext # Implements classical Gettext style accessors. To use this include the # module to the global namespace or wherever you want to use it. # # include I18n::Gettext::Helpers module Helpers def gettext(msgid, options = {}) I18n.t(msgid, { :default => msgid, :separator => '|' }.merge(options)) end alias _ gettext def sgettext(msgid, separator = '|') scope, msgid = I18n::Gettext.extract_scope(msgid, separator) I18n.t(msgid, :scope => scope, :default => msgid, :separator => separator) end alias s_ sgettext def pgettext(msgctxt, msgid) separator = I18n::Gettext::CONTEXT_SEPARATOR sgettext([msgctxt, msgid].join(separator), separator) end alias p_ pgettext def ngettext(msgid, msgid_plural, n = 1) nsgettext(msgid, msgid_plural, n) end alias n_ ngettext # Method signatures: # nsgettext('Fruits|apple', 'apples', 2) # nsgettext(['Fruits|apple', 'apples'], 2) def nsgettext(msgid, msgid_plural, n = 1, separator = '|') if msgid.is_a?(Array) msgid, msgid_plural, n, separator = msgid[0], msgid[1], msgid_plural, n separator = '|' unless separator.is_a?(::String) end scope, msgid = I18n::Gettext.extract_scope(msgid, separator) default = { :one => msgid, :other => msgid_plural } I18n.t(msgid, :default => default, :count => n, :scope => scope, :separator => separator) end alias ns_ nsgettext # Method signatures: # npgettext('Fruits', 'apple', 'apples', 2) # npgettext('Fruits', ['apple', 'apples'], 2) def npgettext(msgctxt, msgid, msgid_plural, n = 1) separator = I18n::Gettext::CONTEXT_SEPARATOR if msgid.is_a?(Array) msgid_plural, msgid, n = msgid[1], [msgctxt, msgid[0]].join(separator), msgid_plural else msgid = [msgctxt, msgid].join(separator) end nsgettext(msgid, msgid_plural, n, separator) end alias np_ npgettext end end end i18n-0.7.0/lib/i18n/gettext/po_parser.rb0000644000004100000410000001513012461054500017652 0ustar www-datawww-data=begin poparser.rb - Generate a .mo Copyright (C) 2003-2009 Masao Mutoh You may redistribute it and/or modify it under the same license terms as Ruby. =end #MODIFIED # removed include GetText etc # added stub translation method _(x) require 'racc/parser' module GetText class PoParser < Racc::Parser def _(x) x end module_eval <<'..end src/poparser.ry modeval..id7a99570e05', 'src/poparser.ry', 108 def unescape(orig) ret = orig.gsub(/\\n/, "\n") ret.gsub!(/\\t/, "\t") ret.gsub!(/\\r/, "\r") ret.gsub!(/\\"/, "\"") ret end def parse(str, data, ignore_fuzzy = true) @comments = [] @data = data @fuzzy = false @msgctxt = "" $ignore_fuzzy = ignore_fuzzy str.strip! @q = [] until str.empty? do case str when /\A\s+/ str = $' when /\Amsgctxt/ @q.push [:MSGCTXT, $&] str = $' when /\Amsgid_plural/ @q.push [:MSGID_PLURAL, $&] str = $' when /\Amsgid/ @q.push [:MSGID, $&] str = $' when /\Amsgstr/ @q.push [:MSGSTR, $&] str = $' when /\A\[(\d+)\]/ @q.push [:PLURAL_NUM, $1] str = $' when /\A\#~(.*)/ $stderr.print _("Warning: obsolete msgid exists.\n") $stderr.print " #{$&}\n" @q.push [:COMMENT, $&] str = $' when /\A\#(.*)/ @q.push [:COMMENT, $&] str = $' when /\A\"(.*)\"/ @q.push [:STRING, $1] str = $' else #c = str[0,1] #@q.push [:STRING, c] str = str[1..-1] end end @q.push [false, '$end'] if $DEBUG @q.each do |a,b| puts "[#{a}, #{b}]" end end @yydebug = true if $DEBUG do_parse if @comments.size > 0 @data.set_comment(:last, @comments.join("\n")) end @data end def next_token @q.shift end def on_message(msgid, msgstr) if msgstr.size > 0 @data[msgid] = msgstr @data.set_comment(msgid, @comments.join("\n")) end @comments.clear @msgctxt = "" end def on_comment(comment) @fuzzy = true if (/fuzzy/ =~ comment) @comments << comment end ..end src/poparser.ry modeval..id7a99570e05 ##### racc 1.4.5 generates ### racc_reduce_table = [ 0, 0, :racc_error, 0, 10, :_reduce_none, 2, 10, :_reduce_none, 2, 10, :_reduce_none, 2, 10, :_reduce_none, 2, 12, :_reduce_5, 1, 13, :_reduce_none, 1, 13, :_reduce_none, 4, 15, :_reduce_8, 5, 16, :_reduce_9, 2, 17, :_reduce_10, 1, 17, :_reduce_none, 3, 18, :_reduce_12, 1, 11, :_reduce_13, 2, 14, :_reduce_14, 1, 14, :_reduce_15 ] racc_reduce_n = 16 racc_shift_n = 26 racc_action_table = [ 3, 13, 5, 7, 9, 15, 16, 17, 20, 17, 13, 17, 13, 13, 11, 17, 23, 20, 13, 17 ] racc_action_check = [ 1, 16, 1, 1, 1, 12, 12, 12, 18, 18, 7, 14, 15, 9, 3, 19, 20, 21, 23, 25 ] racc_action_pointer = [ nil, 0, nil, 14, nil, nil, nil, 3, nil, 6, nil, nil, 0, nil, 4, 5, -6, nil, 2, 8, 8, 11, nil, 11, nil, 12 ] racc_action_default = [ -1, -16, -2, -16, -3, -13, -4, -16, -6, -16, -7, 26, -16, -15, -5, -16, -16, -14, -16, -8, -16, -9, -11, -16, -10, -12 ] racc_goto_table = [ 12, 22, 14, 4, 24, 6, 2, 8, 18, 19, 10, 21, 1, nil, nil, nil, 25 ] racc_goto_check = [ 5, 9, 5, 3, 9, 4, 2, 6, 5, 5, 7, 8, 1, nil, nil, nil, 5 ] racc_goto_pointer = [ nil, 12, 5, 2, 4, -7, 6, 9, -7, -17 ] racc_goto_default = [ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil ] racc_token_table = { false => 0, Object.new => 1, :COMMENT => 2, :MSGID => 3, :MSGCTXT => 4, :MSGID_PLURAL => 5, :MSGSTR => 6, :STRING => 7, :PLURAL_NUM => 8 } racc_use_result_var = true racc_nt_base = 9 Racc_arg = [ racc_action_table, racc_action_check, racc_action_default, racc_action_pointer, racc_goto_table, racc_goto_check, racc_goto_default, racc_goto_pointer, racc_nt_base, racc_reduce_table, racc_token_table, racc_shift_n, racc_reduce_n, racc_use_result_var ] Racc_token_to_s_table = [ '$end', 'error', 'COMMENT', 'MSGID', 'MSGCTXT', 'MSGID_PLURAL', 'MSGSTR', 'STRING', 'PLURAL_NUM', '$start', 'msgfmt', 'comment', 'msgctxt', 'message', 'string_list', 'single_message', 'plural_message', 'msgstr_plural', 'msgstr_plural_line'] Racc_debug_parser = true ##### racc system variables end ##### # reduce 0 omitted # reduce 1 omitted # reduce 2 omitted # reduce 3 omitted # reduce 4 omitted module_eval <<'.,.,', 'src/poparser.ry', 25 def _reduce_5( val, _values, result ) @msgctxt = unescape(val[1]) + "\004" result end .,., # reduce 6 omitted # reduce 7 omitted module_eval <<'.,.,', 'src/poparser.ry', 48 def _reduce_8( val, _values, result ) if @fuzzy and $ignore_fuzzy if val[1] != "" $stderr.print _("Warning: fuzzy message was ignored.\n") $stderr.print " msgid '#{val[1]}'\n" else on_message('', unescape(val[3])) end @fuzzy = false else on_message(@msgctxt + unescape(val[1]), unescape(val[3])) end result = "" result end .,., module_eval <<'.,.,', 'src/poparser.ry', 65 def _reduce_9( val, _values, result ) if @fuzzy and $ignore_fuzzy if val[1] != "" $stderr.print _("Warning: fuzzy message was ignored.\n") $stderr.print "msgid = '#{val[1]}\n" else on_message('', unescape(val[3])) end @fuzzy = false else on_message(@msgctxt + unescape(val[1]) + "\000" + unescape(val[3]), unescape(val[4])) end result = "" result end .,., module_eval <<'.,.,', 'src/poparser.ry', 76 def _reduce_10( val, _values, result ) if val[0].size > 0 result = val[0] + "\000" + val[1] else result = "" end result end .,., # reduce 11 omitted module_eval <<'.,.,', 'src/poparser.ry', 84 def _reduce_12( val, _values, result ) result = val[2] result end .,., module_eval <<'.,.,', 'src/poparser.ry', 91 def _reduce_13( val, _values, result ) on_comment(val[0]) result end .,., module_eval <<'.,.,', 'src/poparser.ry', 99 def _reduce_14( val, _values, result ) result = val.delete_if{|item| item == ""}.join result end .,., module_eval <<'.,.,', 'src/poparser.ry', 103 def _reduce_15( val, _values, result ) result = val[0] result end .,., def _reduce_none( val, _values, result ) result end end # class PoParser end # module GetText i18n-0.7.0/lib/i18n/version.rb0000644000004100000410000000004412461054500015657 0ustar www-datawww-datamodule I18n VERSION = "0.7.0" end i18n-0.7.0/lib/i18n/config.rb0000644000004100000410000001126212461054500015443 0ustar www-datawww-datarequire 'set' module I18n class Config # The only configuration value that is not global and scoped to thread is :locale. # It defaults to the default_locale. def locale @locale ||= default_locale end # Sets the current locale pseudo-globally, i.e. in the Thread.current hash. def locale=(locale) I18n.enforce_available_locales!(locale) @locale = locale && locale.to_sym end # Returns the current backend. Defaults to +Backend::Simple+. def backend @@backend ||= Backend::Simple.new end # Sets the current backend. Used to set a custom backend. def backend=(backend) @@backend = backend end # Returns the current default locale. Defaults to :'en' def default_locale @@default_locale ||= :en end # Sets the current default locale. Used to set a custom default locale. def default_locale=(locale) I18n.enforce_available_locales!(locale) @@default_locale = locale && locale.to_sym end # Returns an array of locales for which translations are available. # Unless you explicitely set these through I18n.available_locales= # the call will be delegated to the backend. def available_locales @@available_locales ||= nil @@available_locales || backend.available_locales end # Caches the available locales list as both strings and symbols in a Set, so # that we can have faster lookups to do the available locales enforce check. def available_locales_set #:nodoc: @@available_locales_set ||= available_locales.inject(Set.new) do |set, locale| set << locale.to_s << locale.to_sym end end # Sets the available locales. def available_locales=(locales) @@available_locales = Array(locales).map { |locale| locale.to_sym } @@available_locales = nil if @@available_locales.empty? @@available_locales_set = nil end # Clears the available locales set so it can be recomputed again after I18n # gets reloaded. def clear_available_locales_set #:nodoc: @@available_locales_set = nil end # Returns the current default scope separator. Defaults to '.' def default_separator @@default_separator ||= '.' end # Sets the current default scope separator. def default_separator=(separator) @@default_separator = separator end # Returns the current exception handler. Defaults to an instance of # I18n::ExceptionHandler. def exception_handler @@exception_handler ||= ExceptionHandler.new end # Sets the exception handler. def exception_handler=(exception_handler) @@exception_handler = exception_handler end # Returns the current handler for situations when interpolation argument # is missing. MissingInterpolationArgument will be raised by default. def missing_interpolation_argument_handler @@missing_interpolation_argument_handler ||= lambda do |missing_key, provided_hash, string| raise MissingInterpolationArgument.new(missing_key, provided_hash, string) end end # Sets the missing interpolation argument handler. It can be any # object that responds to #call. The arguments that will be passed to #call # are the same as for MissingInterpolationArgument initializer. Use +Proc.new+ # if you don't care about arity. # # == Example: # You can supress raising an exception and return string instead: # # I18n.config.missing_interpolation_argument_handler = Proc.new do |key| # "#{key} is missing" # end def missing_interpolation_argument_handler=(exception_handler) @@missing_interpolation_argument_handler = exception_handler end # Allow clients to register paths providing translation data sources. The # backend defines acceptable sources. # # E.g. the provided SimpleBackend accepts a list of paths to translation # files which are either named *.rb and contain plain Ruby Hashes or are # named *.yml and contain YAML data. So for the SimpleBackend clients may # register translation files like this: # I18n.load_path << 'path/to/locale/en.yml' def load_path @@load_path ||= [] end # Sets the load path instance. Custom implementations are expected to # behave like a Ruby Array. def load_path=(load_path) @@load_path = load_path end # Whether or not to verify if locales are in the list of available locales. # Defaults to true. @@enforce_available_locales = true def enforce_available_locales @@enforce_available_locales end def enforce_available_locales=(enforce_available_locales) @@enforce_available_locales = enforce_available_locales end end end i18n-0.7.0/lib/i18n/gettext.rb0000644000004100000410000000122012461054500015653 0ustar www-datawww-datamodule I18n module Gettext PLURAL_SEPARATOR = "\001" CONTEXT_SEPARATOR = "\004" autoload :Helpers, 'i18n/gettext/helpers' @@plural_keys = { :en => [:one, :other] } class << self # returns an array of plural keys for the given locale so that we can # convert from gettext's integer-index based style # TODO move this information to the pluralization module def plural_keys(locale) @@plural_keys[locale] || @@plural_keys[:en] end def extract_scope(msgid, separator) scope = msgid.to_s.split(separator) msgid = scope.pop [scope, msgid] end end end end i18n-0.7.0/lib/i18n/backend.rb0000644000004100000410000000161012461054500015561 0ustar www-datawww-datamodule I18n module Backend autoload :Base, 'i18n/backend/base' autoload :InterpolationCompiler, 'i18n/backend/interpolation_compiler' autoload :Cache, 'i18n/backend/cache' autoload :Cascade, 'i18n/backend/cascade' autoload :Chain, 'i18n/backend/chain' autoload :Fallbacks, 'i18n/backend/fallbacks' autoload :Flatten, 'i18n/backend/flatten' autoload :Gettext, 'i18n/backend/gettext' autoload :KeyValue, 'i18n/backend/key_value' autoload :Memoize, 'i18n/backend/memoize' autoload :Metadata, 'i18n/backend/metadata' autoload :Pluralization, 'i18n/backend/pluralization' autoload :Simple, 'i18n/backend/simple' autoload :Transliterator, 'i18n/backend/transliterator' end end i18n-0.7.0/lib/i18n/backend/0000755000004100000410000000000012461054500015236 5ustar www-datawww-datai18n-0.7.0/lib/i18n/backend/cache.rb0000644000004100000410000000623712461054500016636 0ustar www-datawww-data# This module allows you to easily cache all responses from the backend - thus # speeding up the I18n aspects of your application quite a bit. # # To enable caching you can simply include the Cache module to the Simple # backend - or whatever other backend you are using: # # I18n::Backend::Simple.send(:include, I18n::Backend::Cache) # # You will also need to set a cache store implementation that you want to use: # # I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store) # # You can use any cache implementation you want that provides the same API as # ActiveSupport::Cache (only the methods #fetch and #write are being used). # # The cache_key implementation assumes that you only pass values to # I18n.translate that return a valid key from #hash (see # http://www.ruby-doc.org/core/classes/Object.html#M000337). # # If you use a lambda as a default value in your translation like this: # # I18n.t(:"date.order", :default => lambda {[:month, :day, :year]}) # # Then you will always have a cache miss, because each time this method # is called the lambda will have a different hash value. If you know # the result of the lambda is a constant as in the example above, then # to cache this you can make the lambda a constant, like this: # # DEFAULT_DATE_ORDER = lambda {[:month, :day, :year]} # ... # I18n.t(:"date.order", :default => DEFAULT_DATE_ORDER) # # If the lambda may result in different values for each call then consider # also using the Memoize backend. # module I18n class << self @@cache_store = nil @@cache_namespace = nil def cache_store @@cache_store end def cache_store=(store) @@cache_store = store end def cache_namespace @@cache_namespace end def cache_namespace=(namespace) @@cache_namespace = namespace end def perform_caching? !cache_store.nil? end end module Backend # TODO Should the cache be cleared if new translations are stored? module Cache def translate(locale, key, options = {}) I18n.perform_caching? ? fetch(cache_key(locale, key, options)) { super } : super end protected def fetch(cache_key, &block) result = _fetch(cache_key, &block) throw(:exception, result) if result.is_a?(MissingTranslation) result = result.dup if result.frozen? rescue result result end def _fetch(cache_key, &block) result = I18n.cache_store.read(cache_key) and return result result = catch(:exception, &block) I18n.cache_store.write(cache_key, result) unless result.is_a?(Proc) result end def cache_key(locale, key, options) # This assumes that only simple, native Ruby values are passed to I18n.translate. "i18n/#{I18n.cache_namespace}/#{locale}/#{key.hash}/#{USE_INSPECT_HASH ? options.inspect.hash : options.hash}" end private # In Ruby < 1.9 the following is true: { :foo => 1, :bar => 2 }.hash == { :foo => 2, :bar => 1 }.hash # Therefore we must use the hash of the inspect string instead to avoid cache key colisions. USE_INSPECT_HASH = RUBY_VERSION <= "1.9" end end end i18n-0.7.0/lib/i18n/backend/cascade.rb0000644000004100000410000000416012461054500017147 0ustar www-datawww-data# The Cascade module adds the ability to do cascading lookups to backends that # are compatible to the Simple backend. # # By cascading lookups we mean that for any key that can not be found the # Cascade module strips one segment off the scope part of the key and then # tries to look up the key in that scope. # # E.g. when a lookup for the key :"foo.bar.baz" does not yield a result then # the segment :bar will be stripped off the scope part :"foo.bar" and the new # scope :foo will be used to look up the key :baz. If that does not succeed # then the remaining scope segment :foo will be omitted, too, and again the # key :baz will be looked up (now with no scope). # # To enable a cascading lookup one passes the :cascade option: # # I18n.t(:'foo.bar.baz', :cascade => true) # # This will return the first translation found for :"foo.bar.baz", :"foo.baz" # or :baz in this order. # # The cascading lookup takes precedence over resolving any given defaults. # I.e. defaults will kick in after the cascading lookups haven't succeeded. # # This behavior is useful for libraries like ActiveRecord validations where # the library wants to give users a bunch of more or less fine-grained options # of scopes for a particular key. # # Thanks to Clemens Kofler for the initial idea and implementation! See # http://github.com/clemens/i18n-cascading-backend module I18n module Backend module Cascade def lookup(locale, key, scope = [], options = {}) return super unless cascade = options[:cascade] cascade = { :step => 1 } unless cascade.is_a?(Hash) step = cascade[:step] || 1 offset = cascade[:offset] || 1 separator = options[:separator] || I18n.default_separator skip_root = cascade.has_key?(:skip_root) ? cascade[:skip_root] : true scope = I18n.normalize_keys(nil, key, scope, separator) key = (scope.slice!(-offset, offset) || []).join(separator) begin result = super return result unless result.nil? scope = scope.dup end while (!scope.empty? || !skip_root) && scope.slice!(-step, step) end end end end i18n-0.7.0/lib/i18n/backend/fallbacks.rb0000644000004100000410000000526112461054500017511 0ustar www-datawww-data# I18n locale fallbacks are useful when you want your application to use # translations from other locales when translations for the current locale are # missing. E.g. you might want to use :en translations when translations in # your applications main locale :de are missing. # # To enable locale fallbacks you can simply include the Fallbacks module to # the Simple backend - or whatever other backend you are using: # # I18n::Backend::Simple.include(I18n::Backend::Fallbacks) module I18n @@fallbacks = nil class << self # Returns the current fallbacks implementation. Defaults to +I18n::Locale::Fallbacks+. def fallbacks @@fallbacks ||= I18n::Locale::Fallbacks.new end # Sets the current fallbacks implementation. Use this to set a different fallbacks implementation. def fallbacks=(fallbacks) @@fallbacks = fallbacks end end module Backend module Fallbacks # Overwrites the Base backend translate method so that it will try each # locale given by I18n.fallbacks for the given locale. E.g. for the # locale :"de-DE" it might try the locales :"de-DE", :de and :en # (depends on the fallbacks implementation) until it finds a result with # the given options. If it does not find any result for any of the # locales it will then throw MissingTranslation as usual. # # The default option takes precedence over fallback locales only when # it's a Symbol. When the default contains a String, Proc or Hash # it is evaluated last after all the fallback locales have been tried. def translate(locale, key, options = {}) return super if options[:fallback] default = extract_non_symbol_default!(options) if options[:default] options[:fallback] = true I18n.fallbacks[locale].each do |fallback| begin catch(:exception) do result = super(fallback, key, options) return result unless result.nil? end rescue I18n::InvalidLocale # we do nothing when the locale is invalid, as this is a fallback anyways. end end options.delete(:fallback) return super(locale, nil, options.merge(:default => default)) if default throw(:exception, I18n::MissingTranslation.new(locale, key, options)) end def extract_non_symbol_default!(options) defaults = [options[:default]].flatten first_non_symbol_default = defaults.detect{|default| !default.is_a?(Symbol)} if first_non_symbol_default options[:default] = defaults[0, defaults.index(first_non_symbol_default)] end return first_non_symbol_default end end end end i18n-0.7.0/lib/i18n/backend/transliterator.rb0000644000004100000410000001043312461054500020641 0ustar www-datawww-data# encoding: utf-8 module I18n module Backend module Transliterator DEFAULT_REPLACEMENT_CHAR = "?" # Given a locale and a UTF-8 string, return the locale's ASCII # approximation for the string. def transliterate(locale, string, replacement = nil) @transliterators ||= {} @transliterators[locale] ||= Transliterator.get I18n.t(:'i18n.transliterate.rule', :locale => locale, :resolve => false, :default => {}) @transliterators[locale].transliterate(string, replacement) end # Get a transliterator instance. def self.get(rule = nil) if !rule || rule.kind_of?(Hash) HashTransliterator.new(rule) elsif rule.kind_of? Proc ProcTransliterator.new(rule) else raise I18n::ArgumentError, "Transliteration rule must be a proc or a hash." end end # A transliterator which accepts a Proc as its transliteration rule. class ProcTransliterator def initialize(rule) @rule = rule end def transliterate(string, replacement = nil) @rule.call(string) end end # A transliterator which accepts a Hash of characters as its translation # rule. class HashTransliterator DEFAULT_APPROXIMATIONS = { "À"=>"A", "Á"=>"A", "Â"=>"A", "Ã"=>"A", "Ä"=>"A", "Å"=>"A", "Æ"=>"AE", "Ç"=>"C", "È"=>"E", "É"=>"E", "Ê"=>"E", "Ë"=>"E", "Ì"=>"I", "Í"=>"I", "Î"=>"I", "Ï"=>"I", "Ð"=>"D", "Ñ"=>"N", "Ò"=>"O", "Ó"=>"O", "Ô"=>"O", "Õ"=>"O", "Ö"=>"O", "×"=>"x", "Ø"=>"O", "Ù"=>"U", "Ú"=>"U", "Û"=>"U", "Ü"=>"U", "Ý"=>"Y", "Þ"=>"Th", "ß"=>"ss", "à"=>"a", "á"=>"a", "â"=>"a", "ã"=>"a", "ä"=>"a", "å"=>"a", "æ"=>"ae", "ç"=>"c", "è"=>"e", "é"=>"e", "ê"=>"e", "ë"=>"e", "ì"=>"i", "í"=>"i", "î"=>"i", "ï"=>"i", "ð"=>"d", "ñ"=>"n", "ò"=>"o", "ó"=>"o", "ô"=>"o", "õ"=>"o", "ö"=>"o", "ø"=>"o", "ù"=>"u", "ú"=>"u", "û"=>"u", "ü"=>"u", "ý"=>"y", "þ"=>"th", "ÿ"=>"y", "Ā"=>"A", "ā"=>"a", "Ă"=>"A", "ă"=>"a", "Ą"=>"A", "ą"=>"a", "Ć"=>"C", "ć"=>"c", "Ĉ"=>"C", "ĉ"=>"c", "Ċ"=>"C", "ċ"=>"c", "Č"=>"C", "č"=>"c", "Ď"=>"D", "ď"=>"d", "Đ"=>"D", "đ"=>"d", "Ē"=>"E", "ē"=>"e", "Ĕ"=>"E", "ĕ"=>"e", "Ė"=>"E", "ė"=>"e", "Ę"=>"E", "ę"=>"e", "Ě"=>"E", "ě"=>"e", "Ĝ"=>"G", "ĝ"=>"g", "Ğ"=>"G", "ğ"=>"g", "Ġ"=>"G", "ġ"=>"g", "Ģ"=>"G", "ģ"=>"g", "Ĥ"=>"H", "ĥ"=>"h", "Ħ"=>"H", "ħ"=>"h", "Ĩ"=>"I", "ĩ"=>"i", "Ī"=>"I", "ī"=>"i", "Ĭ"=>"I", "ĭ"=>"i", "Į"=>"I", "į"=>"i", "İ"=>"I", "ı"=>"i", "IJ"=>"IJ", "ij"=>"ij", "Ĵ"=>"J", "ĵ"=>"j", "Ķ"=>"K", "ķ"=>"k", "ĸ"=>"k", "Ĺ"=>"L", "ĺ"=>"l", "Ļ"=>"L", "ļ"=>"l", "Ľ"=>"L", "ľ"=>"l", "Ŀ"=>"L", "ŀ"=>"l", "Ł"=>"L", "ł"=>"l", "Ń"=>"N", "ń"=>"n", "Ņ"=>"N", "ņ"=>"n", "Ň"=>"N", "ň"=>"n", "ʼn"=>"'n", "Ŋ"=>"NG", "ŋ"=>"ng", "Ō"=>"O", "ō"=>"o", "Ŏ"=>"O", "ŏ"=>"o", "Ő"=>"O", "ő"=>"o", "Œ"=>"OE", "œ"=>"oe", "Ŕ"=>"R", "ŕ"=>"r", "Ŗ"=>"R", "ŗ"=>"r", "Ř"=>"R", "ř"=>"r", "Ś"=>"S", "ś"=>"s", "Ŝ"=>"S", "ŝ"=>"s", "Ş"=>"S", "ş"=>"s", "Š"=>"S", "š"=>"s", "Ţ"=>"T", "ţ"=>"t", "Ť"=>"T", "ť"=>"t", "Ŧ"=>"T", "ŧ"=>"t", "Ũ"=>"U", "ũ"=>"u", "Ū"=>"U", "ū"=>"u", "Ŭ"=>"U", "ŭ"=>"u", "Ů"=>"U", "ů"=>"u", "Ű"=>"U", "ű"=>"u", "Ų"=>"U", "ų"=>"u", "Ŵ"=>"W", "ŵ"=>"w", "Ŷ"=>"Y", "ŷ"=>"y", "Ÿ"=>"Y", "Ź"=>"Z", "ź"=>"z", "Ż"=>"Z", "ż"=>"z", "Ž"=>"Z", "ž"=>"z" }.freeze def initialize(rule = nil) @rule = rule add DEFAULT_APPROXIMATIONS.dup add rule if rule end def transliterate(string, replacement = nil) string.gsub(/[^\x00-\x7f]/u) do |char| approximations[char] || replacement || DEFAULT_REPLACEMENT_CHAR end end private def approximations @approximations ||= {} end # Add transliteration rules to the approximations hash. def add(hash) hash.each do |key, value| approximations[key.to_s] = value.to_s end end end end end endi18n-0.7.0/lib/i18n/backend/metadata.rb0000644000004100000410000000401212461054500017340 0ustar www-datawww-data# I18n translation metadata is useful when you want to access information # about how a translation was looked up, pluralized or interpolated in # your application. # # msg = I18n.t(:message, :default => 'Hi!', :scope => :foo) # msg.translation_metadata # # => { :key => :message, :scope => :foo, :default => 'Hi!' } # # If a :count option was passed to #translate it will be set to the metadata. # Likewise, if any interpolation variables were passed they will also be set. # # To enable translation metadata you can simply include the Metadata module # into the Simple backend class - or whatever other backend you are using: # # I18n::Backend::Simple.include(I18n::Backend::Metadata) # module I18n module Backend module Metadata class << self def included(base) Object.class_eval do def translation_metadata @translation_metadata ||= {} end def translation_metadata=(translation_metadata) @translation_metadata = translation_metadata end end unless Object.method_defined?(:translation_metadata) end end def translate(locale, key, options = {}) metadata = { :locale => locale, :key => key, :scope => options[:scope], :default => options[:default], :separator => options[:separator], :values => options.reject { |name, value| RESERVED_KEYS.include?(name) } } with_metadata(metadata) { super } end def interpolate(locale, entry, values = {}) metadata = entry.translation_metadata.merge(:original => entry) with_metadata(metadata) { super } end def pluralize(locale, entry, count) with_metadata(:count => count) { super } end protected def with_metadata(metadata, &block) result = yield result.translation_metadata = result.translation_metadata.merge(metadata) if result result end end end end i18n-0.7.0/lib/i18n/backend/simple.rb0000644000004100000410000000544312461054500017062 0ustar www-datawww-datamodule I18n module Backend # A simple backend that reads translations from YAML files and stores them in # an in-memory hash. Relies on the Base backend. # # The implementation is provided by a Implementation module allowing to easily # extend Simple backend's behavior by including modules. E.g.: # # module I18n::Backend::Pluralization # def pluralize(*args) # # extended pluralization logic # super # end # end # # I18n::Backend::Simple.include(I18n::Backend::Pluralization) class Simple (class << self; self; end).class_eval { public :include } module Implementation include Base def initialized? @initialized ||= false end # Stores translations for the given locale in memory. # This uses a deep merge for the translations hash, so existing # translations will be overwritten by new ones only at the deepest # level of the hash. def store_translations(locale, data, options = {}) locale = locale.to_sym translations[locale] ||= {} data = data.deep_symbolize_keys translations[locale].deep_merge!(data) end # Get available locales from the translations hash def available_locales init_translations unless initialized? translations.inject([]) do |locales, (locale, data)| locales << locale unless (data.keys - [:i18n]).empty? locales end end # Clean up translations hash and set initialized to false on reload! def reload! @initialized = false @translations = nil super end protected def init_translations load_translations @initialized = true end def translations @translations ||= {} end # Looks up a translation from the translations hash. Returns nil if # eiher key is nil, or locale, scope or key do not exist as a key in the # nested translations hash. Splits keys or scopes containing dots # into multiple keys, i.e. currency.format is regarded the same as # %w(currency format). def lookup(locale, key, scope = [], options = {}) init_translations unless initialized? keys = I18n.normalize_keys(locale, key, scope, options[:separator]) keys.inject(translations) do |result, _key| _key = _key.to_sym return nil unless result.is_a?(Hash) && result.has_key?(_key) result = result[_key] result = resolve(locale, _key, result, options.merge(:scope => nil)) if result.is_a?(Symbol) result end end end include Implementation end end end i18n-0.7.0/lib/i18n/backend/interpolation_compiler.rb0000644000004100000410000000725512461054500022355 0ustar www-datawww-data# The InterpolationCompiler module contains optimizations that can tremendously # speed up the interpolation process on the Simple backend. # # It works by defining a pre-compiled method on stored translation Strings that # already bring all the knowledge about contained interpolation variables etc. # so that the actual recurring interpolation will be very fast. # # To enable pre-compiled interpolations you can simply include the # InterpolationCompiler module to the Simple backend: # # I18n::Backend::Simple.include(I18n::Backend::InterpolationCompiler) # # Note that InterpolationCompiler does not yield meaningful results and consequently # should not be used with Ruby 1.9 (YARV) but improves performance everywhere else # (jRuby, Rubinius). module I18n module Backend module InterpolationCompiler module Compiler extend self TOKENIZER = /(%%\{[^\}]+\}|%\{[^\}]+\})/ INTERPOLATION_SYNTAX_PATTERN = /(%)?(%\{([^\}]+)\})/ def compile_if_an_interpolation(string) if interpolated_str?(string) string.instance_eval <<-RUBY_EVAL, __FILE__, __LINE__ def i18n_interpolate(v = {}) "#{compiled_interpolation_body(string)}" end RUBY_EVAL end string end def interpolated_str?(str) str.kind_of?(::String) && str =~ INTERPOLATION_SYNTAX_PATTERN end protected # tokenize("foo %{bar} baz %%{buz}") # => ["foo ", "%{bar}", " baz ", "%%{buz}"] def tokenize(str) str.split(TOKENIZER) end def compiled_interpolation_body(str) tokenize(str).map do |token| (matchdata = token.match(INTERPOLATION_SYNTAX_PATTERN)) ? handle_interpolation_token(token, matchdata) : escape_plain_str(token) end.join end def handle_interpolation_token(interpolation, matchdata) escaped, pattern, key = matchdata.values_at(1, 2, 3) escaped ? pattern : compile_interpolation_token(key.to_sym) end def compile_interpolation_token(key) "\#{#{interpolate_or_raise_missing(key)}}" end def interpolate_or_raise_missing(key) escaped_key = escape_key_sym(key) RESERVED_KEYS.include?(key) ? reserved_key(escaped_key) : interpolate_key(escaped_key) end def interpolate_key(key) [direct_key(key), nil_key(key), missing_key(key)].join('||') end def direct_key(key) "((t = v[#{key}]) && t.respond_to?(:call) ? t.call : t)" end def nil_key(key) "(v.has_key?(#{key}) && '')" end def missing_key(key) "I18n.config.missing_interpolation_argument_handler.call(#{key}, v, self)" end def reserved_key(key) "raise(ReservedInterpolationKey.new(#{key}, self))" end def escape_plain_str(str) str.gsub(/"|\\|#/) {|x| "\\#{x}"} end def escape_key_sym(key) # rely on Ruby to do all the hard work :) key.to_sym.inspect end end def interpolate(locale, string, values) if string.respond_to?(:i18n_interpolate) string.i18n_interpolate(values) elsif values super else string end end def store_translations(locale, data, options = {}) compile_all_strings_in(data) super end protected def compile_all_strings_in(data) data.each_value do |value| Compiler.compile_if_an_interpolation(value) compile_all_strings_in(value) if value.kind_of?(Hash) end end end end end i18n-0.7.0/lib/i18n/backend/chain.rb0000644000004100000410000000645712461054500016661 0ustar www-datawww-datamodule I18n module Backend # Backend that chains multiple other backends and checks each of them when # a translation needs to be looked up. This is useful when you want to use # standard translations with a Simple backend but store custom application # translations in a database or other backends. # # To use the Chain backend instantiate it and set it to the I18n module. # You can add chained backends through the initializer or backends # accessor: # # # preserves the existing Simple backend set to I18n.backend # I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend) # # The implementation assumes that all backends added to the Chain implement # a lookup method with the same API as Simple backend does. class Chain module Implementation include Base attr_accessor :backends def initialize(*backends) self.backends = backends end def reload! backends.each { |backend| backend.reload! } end def store_translations(locale, data, options = {}) backends.first.store_translations(locale, data, options) end def available_locales backends.map { |backend| backend.available_locales }.flatten.uniq end def translate(locale, key, default_options = {}) namespace = nil options = default_options.except(:default) backends.each do |backend| catch(:exception) do options = default_options if backend == backends.last translation = backend.translate(locale, key, options) if namespace_lookup?(translation, options) namespace = _deep_merge(translation, namespace || {}) elsif !translation.nil? return translation end end end return namespace if namespace throw(:exception, I18n::MissingTranslation.new(locale, key, options)) end def exists?(locale, key) backends.any? do |backend| backend.exists?(locale, key) end end def localize(locale, object, format = :default, options = {}) backends.each do |backend| catch(:exception) do result = backend.localize(locale, object, format, options) and return result end end throw(:exception, I18n::MissingTranslation.new(locale, format, options)) end protected def namespace_lookup?(result, options) result.is_a?(Hash) && !options.has_key?(:count) end private # This is approximately what gets used in ActiveSupport. # However since we are not guaranteed to run in an ActiveSupport context # it is wise to have our own copy. We underscore it # to not pollute the namespace of the including class. def _deep_merge(hash, other_hash) copy = hash.dup other_hash.each_pair do |k,v| value_from_other = hash[k] copy[k] = value_from_other.is_a?(Hash) && v.is_a?(Hash) ? _deep_merge(value_from_other, v) : v end copy end end include Implementation end end end i18n-0.7.0/lib/i18n/backend/memoize.rb0000644000004100000410000000247512461054500017240 0ustar www-datawww-data# Memoize module simply memoizes the values returned by lookup using # a flat hash and can tremendously speed up the lookup process in a backend. # # To enable it you can simply include the Memoize module to your backend: # # I18n::Backend::Simple.include(I18n::Backend::Memoize) # # Notice that it's the responsibility of the backend to define whenever the # cache should be cleaned. module I18n module Backend module Memoize def available_locales @memoized_locales ||= super end def store_translations(locale, data, options = {}) reset_memoizations!(locale) super end def reload! reset_memoizations! super end protected def lookup(locale, key, scope = nil, options = {}) flat_key = I18n::Backend::Flatten.normalize_flat_keys(locale, key, scope, options[:separator]).to_sym flat_hash = memoized_lookup[locale.to_sym] flat_hash.key?(flat_key) ? flat_hash[flat_key] : (flat_hash[flat_key] = super) end def memoized_lookup @memoized_lookup ||= Hash.new { |h, k| h[k] = {} } end def reset_memoizations!(locale=nil) @memoized_locales = nil (locale ? memoized_lookup[locale.to_sym] : memoized_lookup).clear end end end end i18n-0.7.0/lib/i18n/backend/gettext.rb0000644000004100000410000000466012461054500017255 0ustar www-datawww-datarequire 'i18n/gettext' require 'i18n/gettext/po_parser' # Experimental support for using Gettext po files to store translations. # # To use this you can simply include the module to the Simple backend - or # whatever other backend you are using. # # I18n::Backend::Simple.include(I18n::Backend::Gettext) # # Now you should be able to include your Gettext translation (*.po) files to # the I18n.load_path so they're loaded to the backend and you can use them as # usual: # # I18n.load_path += Dir["path/to/locales/*.po"] # # Following the Gettext convention this implementation expects that your # translation files are named by their locales. E.g. the file en.po would # contain the translations for the English locale. module I18n module Backend module Gettext class PoData < Hash def set_comment(msgid_or_sym, comment) # ignore end end protected def load_po(filename) locale = ::File.basename(filename, '.po').to_sym data = normalize(locale, parse(filename)) { locale => data } end def parse(filename) GetText::PoParser.new.parse(::File.read(filename), PoData.new) end def normalize(locale, data) data.inject({}) do |result, (key, value)| unless key.nil? || key.empty? key = key.gsub(I18n::Gettext::CONTEXT_SEPARATOR, '|') key, value = normalize_pluralization(locale, key, value) if key.index("\000") parts = key.split('|').reverse normalized = parts.inject({}) do |_normalized, part| { part => _normalized.empty? ? value : _normalized } end result.deep_merge!(normalized) end result end end def normalize_pluralization(locale, key, value) # FIXME po_parser includes \000 chars that can not be turned into Symbols key = key.gsub("\000", I18n::Gettext::PLURAL_SEPARATOR).split(I18n::Gettext::PLURAL_SEPARATOR).first keys = I18n::Gettext.plural_keys(locale) values = value.split("\000") raise "invalid number of plurals: #{values.size}, keys: #{keys.inspect} on #{locale} locale for msgid #{key.inspect} with values #{values.inspect}" if values.size != keys.size result = {} values.each_with_index { |_value, ix| result[keys[ix]] = _value } [key, result] end end end end i18n-0.7.0/lib/i18n/backend/key_value.rb0000644000004100000410000000671112461054500017554 0ustar www-datawww-datarequire 'i18n/backend/base' require 'active_support/json' module I18n module Backend # This is a basic backend for key value stores. It receives on # initialization the store, which should respond to three methods: # # * store#[](key) - Used to get a value # * store#[]=(key, value) - Used to set a value # * store#keys - Used to get all keys # # Since these stores only supports string, all values are converted # to JSON before being stored, allowing it to also store booleans, # hashes and arrays. However, this store does not support Procs. # # As the ActiveRecord backend, Symbols are just supported when loading # translations from the filesystem or through explicit store translations. # # Also, avoid calling I18n.available_locales since it's a somehow # expensive operation in most stores. # # == Example # # To setup I18n to use TokyoCabinet in memory is quite straightforward: # # require 'rufus/tokyo/cabinet' # gem install rufus-tokyo # I18n.backend = I18n::Backend::KeyValue.new(Rufus::Tokyo::Cabinet.new('*')) # # == Performance # # You may make this backend even faster by including the Memoize module. # However, notice that you should properly clear the cache if you change # values directly in the key-store. # # == Subtrees # # In most backends, you are allowed to retrieve part of a translation tree: # # I18n.backend.store_translations :en, :foo => { :bar => :baz } # I18n.t "foo" #=> { :bar => :baz } # # This backend supports this feature by default, but it slows down the storage # of new data considerably and makes hard to delete entries. That said, you are # allowed to disable the storage of subtrees on initialization: # # I18n::Backend::KeyValue.new(@store, false) # # This is useful if you are using a KeyValue backend chained to a Simple backend. class KeyValue module Implementation attr_accessor :store include Base, Flatten def initialize(store, subtrees=true) @store, @subtrees = store, subtrees end def store_translations(locale, data, options = {}) escape = options.fetch(:escape, true) flatten_translations(locale, data, escape, @subtrees).each do |key, value| key = "#{locale}.#{key}" case value when Hash if @subtrees && (old_value = @store[key]) old_value = ActiveSupport::JSON.decode(old_value) value = old_value.deep_symbolize_keys.deep_merge!(value) if old_value.is_a?(Hash) end when Proc raise "Key-value stores cannot handle procs" end @store[key] = ActiveSupport::JSON.encode(value) unless value.is_a?(Symbol) end end def available_locales locales = @store.keys.map { |k| k =~ /\./; $` } locales.uniq! locales.compact! locales.map! { |k| k.to_sym } locales end protected def lookup(locale, key, scope = [], options = {}) key = normalize_flat_keys(locale, key, scope, options[:separator]) value = @store["#{locale}.#{key}"] value = ActiveSupport::JSON.decode(value) if value value.is_a?(Hash) ? value.deep_symbolize_keys : value end end include Implementation end end end i18n-0.7.0/lib/i18n/backend/flatten.rb0000644000004100000410000000734612461054500017232 0ustar www-datawww-datamodule I18n module Backend # This module contains several helpers to assist flattening translations. # You may want to flatten translations for: # # 1) speed up lookups, as in the Memoize backend; # 2) In case you want to store translations in a data store, as in ActiveRecord backend; # # You can check both backends above for some examples. # This module also keeps all links in a hash so they can be properly resolved when flattened. module Flatten SEPARATOR_ESCAPE_CHAR = "\001" FLATTEN_SEPARATOR = "." # normalize_keys the flatten way. This method is significantly faster # and creates way less objects than the one at I18n.normalize_keys. # It also handles escaping the translation keys. def self.normalize_flat_keys(locale, key, scope, separator) keys = [scope, key].flatten.compact separator ||= I18n.default_separator if separator != FLATTEN_SEPARATOR keys.map! do |k| k.to_s.tr("#{FLATTEN_SEPARATOR}#{separator}", "#{SEPARATOR_ESCAPE_CHAR}#{FLATTEN_SEPARATOR}") end end keys.join(".") end # Receives a string and escape the default separator. def self.escape_default_separator(key) #:nodoc: key.to_s.tr(FLATTEN_SEPARATOR, SEPARATOR_ESCAPE_CHAR) end # Shortcut to I18n::Backend::Flatten.normalize_flat_keys # and then resolve_links. def normalize_flat_keys(locale, key, scope, separator) key = I18n::Backend::Flatten.normalize_flat_keys(locale, key, scope, separator) resolve_link(locale, key) end # Store flattened links. def links @links ||= Hash.new { |h,k| h[k] = {} } end # Flatten keys for nested Hashes by chaining up keys: # # >> { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}.wind # => { "a.b.c" => "d", "a.b.e" => "f", "a.g" => "h", "i" => "j" } # def flatten_keys(hash, escape, prev_key=nil, &block) hash.each_pair do |key, value| key = escape_default_separator(key) if escape curr_key = [prev_key, key].compact.join(FLATTEN_SEPARATOR).to_sym yield curr_key, value flatten_keys(value, escape, curr_key, &block) if value.is_a?(Hash) end end # Receives a hash of translations (where the key is a locale and # the value is another hash) and return a hash with all # translations flattened. # # Nested hashes are included in the flattened hash just if subtree # is true and Symbols are automatically stored as links. def flatten_translations(locale, data, escape, subtree) hash = {} flatten_keys(data, escape) do |key, value| if value.is_a?(Hash) hash[key] = value if subtree else store_link(locale, key, value) if value.is_a?(Symbol) hash[key] = value end end hash end protected def store_link(locale, key, link) links[locale.to_sym][key.to_s] = link.to_s end def resolve_link(locale, key) key, locale = key.to_s, locale.to_sym links = self.links[locale] if links.key?(key) links[key] elsif link = find_link(locale, key) store_link(locale, key, key.gsub(*link)) else key end end def find_link(locale, key) #:nodoc: links[locale].each do |from, to| return [from, to] if key[0, from.length] == from end && nil end def escape_default_separator(key) #:nodoc: I18n::Backend::Flatten.escape_default_separator(key) end end end endi18n-0.7.0/lib/i18n/backend/base.rb0000644000004100000410000001727712461054500016513 0ustar www-datawww-datarequire 'yaml' require 'i18n/core_ext/hash' require 'i18n/core_ext/kernel/suppress_warnings' module I18n module Backend module Base include I18n::Backend::Transliterator # Accepts a list of paths to translation files. Loads translations from # plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml # for details. def load_translations(*filenames) filenames = I18n.load_path if filenames.empty? filenames.flatten.each { |filename| load_file(filename) } end # This method receives a locale, a data hash and options for storing translations. # Should be implemented def store_translations(locale, data, options = {}) raise NotImplementedError end def translate(locale, key, options = {}) raise InvalidLocale.new(locale) unless locale entry = key && lookup(locale, key, options[:scope], options) if options.empty? entry = resolve(locale, key, entry, options) else count, default = options.values_at(:count, :default) values = options.except(*RESERVED_KEYS) entry = entry.nil? && default ? default(locale, key, default, options) : resolve(locale, key, entry, options) end throw(:exception, I18n::MissingTranslation.new(locale, key, options)) if entry.nil? entry = entry.dup if entry.is_a?(String) entry = pluralize(locale, entry, count) if count entry = interpolate(locale, entry, values) if values entry end def exists?(locale, key) lookup(locale, key) != nil end # Acts the same as +strftime+, but uses a localized version of the # format string. Takes a key from the date/time formats translations as # a format argument (e.g., :short in :'date.formats'). def localize(locale, object, format = :default, options = {}) raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime) if Symbol === format key = format type = object.respond_to?(:sec) ? 'time' : 'date' options = options.merge(:raise => true, :object => object, :locale => locale) format = I18n.t(:"#{type}.formats.#{key}", options) end # format = resolve(locale, object, format, options) format = format.to_s.gsub(/%[aAbBpP]/) do |match| case match when '%a' then I18n.t(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday] when '%A' then I18n.t(:"date.day_names", :locale => locale, :format => format)[object.wday] when '%b' then I18n.t(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon] when '%B' then I18n.t(:"date.month_names", :locale => locale, :format => format)[object.mon] when '%p' then I18n.t(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format).upcase if object.respond_to? :hour when '%P' then I18n.t(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format).downcase if object.respond_to? :hour end end object.strftime(format) end # Returns an array of locales for which translations are available # ignoring the reserved translation meta data key :i18n. def available_locales raise NotImplementedError end def reload! end protected # The method which actually looks up for the translation in the store. def lookup(locale, key, scope = [], options = {}) raise NotImplementedError end # Evaluates defaults. # If given subject is an Array, it walks the array and returns the # first translation that can be resolved. Otherwise it tries to resolve # the translation directly. def default(locale, object, subject, options = {}) options = options.dup.reject { |key, value| key == :default } case subject when Array subject.each do |item| result = resolve(locale, object, item, options) and return result end and nil else resolve(locale, object, subject, options) end end # Resolves a translation. # If the given subject is a Symbol, it will be translated with the # given options. If it is a Proc then it will be evaluated. All other # subjects will be returned directly. def resolve(locale, object, subject, options = {}) return subject if options[:resolve] == false result = catch(:exception) do case subject when Symbol I18n.translate(subject, options.merge(:locale => locale, :throw => true)) when Proc date_or_time = options.delete(:object) || object resolve(locale, object, subject.call(date_or_time, options)) else subject end end result unless result.is_a?(MissingTranslation) end # Picks a translation from a pluralized mnemonic subkey according to English # pluralization rules : # - It will pick the :one subkey if count is equal to 1. # - It will pick the :other subkey otherwise. # - It will pick the :zero subkey in the special case where count is # equal to 0 and there is a :zero subkey present. This behaviour is # not stand with regards to the CLDR pluralization rules. # Other backends can implement more flexible or complex pluralization rules. def pluralize(locale, entry, count) return entry unless entry.is_a?(Hash) && count key = :zero if count == 0 && entry.has_key?(:zero) key ||= count == 1 ? :one : :other raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key) entry[key] end # Interpolates values into a given string. # # interpolate "file %{file} opened by %%{user}", :file => 'test.txt', :user => 'Mr. X' # # => "file test.txt opened by %{user}" def interpolate(locale, string, values = {}) if string.is_a?(::String) && !values.empty? I18n.interpolate(string, values) else string end end # Loads a single translations file by delegating to #load_rb or # #load_yml depending on the file extension and directly merges the # data to the existing translations. Raises I18n::UnknownFileType # for all other file extensions. def load_file(filename) type = File.extname(filename).tr('.', '').downcase raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}", true) data = send(:"load_#{type}", filename) unless data.is_a?(Hash) raise InvalidLocaleData.new(filename, 'expects it to return a hash, but does not') end data.each { |locale, d| store_translations(locale, d || {}) } end # Loads a plain Ruby translations file. eval'ing the file must yield # a Hash containing translation data with locales as toplevel keys. def load_rb(filename) eval(IO.read(filename), binding, filename) end # Loads a YAML translations file. The data must have locales as # toplevel keys. def load_yml(filename) begin YAML.load_file(filename) rescue TypeError, ScriptError, StandardError => e raise InvalidLocaleData.new(filename, e.inspect) end end end end end i18n-0.7.0/lib/i18n/backend/pluralization.rb0000644000004100000410000000405312461054500020462 0ustar www-datawww-data# I18n Pluralization are useful when you want your application to # customize pluralization rules. # # To enable locale specific pluralizations you can simply include the # Pluralization module to the Simple backend - or whatever other backend you # are using. # # I18n::Backend::Simple.include(I18n::Backend::Pluralization) # # You also need to make sure to provide pluralization algorithms to the # backend, i.e. include them to your I18n.load_path accordingly. module I18n module Backend module Pluralization # Overwrites the Base backend translate method so that it will check the # translation meta data space (:i18n) for a locale specific pluralization # rule and use it to pluralize the given entry. I.e. the library expects # pluralization rules to be stored at I18n.t(:'i18n.plural.rule') # # Pluralization rules are expected to respond to #call(count) and # return a pluralization key. Valid keys depend on the translation data # hash (entry) but it is generally recommended to follow CLDR's style, # i.e., return one of the keys :zero, :one, :few, :many, :other. # # The :zero key is always picked directly when count equals 0 AND the # translation data has the key :zero. This way translators are free to # either pick a special :zero translation even for languages where the # pluralizer does not return a :zero key. def pluralize(locale, entry, count) return entry unless entry.is_a?(Hash) and count pluralizer = pluralizer(locale) if pluralizer.respond_to?(:call) key = count == 0 && entry.has_key?(:zero) ? :zero : pluralizer.call(count) raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key) entry[key] else super end end protected def pluralizers @pluralizers ||= {} end def pluralizer(locale) pluralizers[locale] ||= I18n.t(:'i18n.plural.rule', :locale => locale, :resolve => false) end end end end i18n-0.7.0/lib/i18n/exceptions.rb0000644000004100000410000000565112461054500016364 0ustar www-datawww-datarequire 'cgi' module I18n # Handles exceptions raised in the backend. All exceptions except for # MissingTranslationData exceptions are re-thrown. When a MissingTranslationData # was caught the handler returns an error message string containing the key/scope. # Note that the exception handler is not called when the option :throw was given. class ExceptionHandler include Module.new { def call(exception, locale, key, options) case exception when MissingTranslation exception.message when Exception raise exception else throw :exception, exception end end } end class ArgumentError < ::ArgumentError; end class InvalidLocale < ArgumentError attr_reader :locale def initialize(locale) @locale = locale super "#{locale.inspect} is not a valid locale" end end class InvalidLocaleData < ArgumentError attr_reader :filename def initialize(filename, exception_message) @filename, @exception_message = filename, exception_message super "can not load translations from #{filename}: #{exception_message}" end end class MissingTranslation module Base attr_reader :locale, :key, :options def initialize(locale, key, options = nil) @key, @locale, @options = key, locale, options.dup || {} options.each { |k, v| self.options[k] = v.inspect if v.is_a?(Proc) } end def keys @keys ||= I18n.normalize_keys(locale, key, options[:scope]).tap do |keys| keys << 'no key' if keys.size < 2 end end def message "translation missing: #{keys.join('.')}" end alias :to_s :message def to_exception MissingTranslationData.new(locale, key, options) end end include Base end class MissingTranslationData < ArgumentError include MissingTranslation::Base end class InvalidPluralizationData < ArgumentError attr_reader :entry, :count def initialize(entry, count) @entry, @count = entry, count super "translation data #{entry.inspect} can not be used with :count => #{count}" end end class MissingInterpolationArgument < ArgumentError attr_reader :key, :values, :string def initialize(key, values, string) @key, @values, @string = key, values, string super "missing interpolation argument #{key.inspect} in #{string.inspect} (#{values.inspect} given)" end end class ReservedInterpolationKey < ArgumentError attr_reader :key, :string def initialize(key, string) @key, @string = key, string super "reserved key #{key.inspect} used in #{string.inspect}" end end class UnknownFileType < ArgumentError attr_reader :type, :filename def initialize(type, filename) @type, @filename = type, filename super "can not load translations from #{filename}, the file type #{type} is not known" end end end i18n-0.7.0/lib/i18n/interpolate/0000755000004100000410000000000012461054500016175 5ustar www-datawww-datai18n-0.7.0/lib/i18n/interpolate/ruby.rb0000644000004100000410000000261712461054500017511 0ustar www-datawww-data# heavily based on Masao Mutoh's gettext String interpolation extension # http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb module I18n INTERPOLATION_PATTERN = Regexp.union( /%%/, /%\{(\w+)\}/, # matches placeholders like "%{foo}" /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%.d" ) class << self # Return String or raises MissingInterpolationArgument exception. # Missing argument's logic is handled by I18n.config.missing_interpolation_argument_handler. def interpolate(string, values) raise ReservedInterpolationKey.new($1.to_sym, string) if string =~ RESERVED_KEYS_PATTERN raise ArgumentError.new('Interpolation values must be a Hash.') unless values.kind_of?(Hash) interpolate_hash(string, values) end def interpolate_hash(string, values) string.gsub(INTERPOLATION_PATTERN) do |match| if match == '%%' '%' else key = ($1 || $2).to_sym value = if values.key?(key) values[key] else config.missing_interpolation_argument_handler.call(key, values, string) end value = value.call(values) if value.respond_to?(:call) $3 ? sprintf("%#{$3}", value) : value end end end end end i18n-0.7.0/lib/i18n/locale.rb0000644000004100000410000000017612461054500015437 0ustar www-datawww-datamodule I18n module Locale autoload :Fallbacks, 'i18n/locale/fallbacks' autoload :Tag, 'i18n/locale/tag' end end i18n-0.7.0/lib/i18n/locale/0000755000004100000410000000000012461054500015106 5ustar www-datawww-datai18n-0.7.0/lib/i18n/locale/fallbacks.rb0000644000004100000410000000644212461054500017363 0ustar www-datawww-data# Locale Fallbacks # # Extends the I18n module to hold a fallbacks instance which is set to an # instance of I18n::Locale::Fallbacks by default but can be swapped with a # different implementation. # # Locale fallbacks will compute a number of fallback locales for a given locale. # For example: # #

# I18n.fallbacks[:"es-MX"] # => [:"es-MX", :es, :en] 
# # Locale fallbacks always fall back to # # * all parent locales of a given locale (e.g. :es for :"es-MX") first, # * the current default locales and all of their parents second # # The default locales are set to [I18n.default_locale] by default but can be # set to something else. # # One can additionally add any number of additional fallback locales manually. # These will be added before the default locales to the fallback chain. For # example: # # # using the default locale as default fallback locale # # I18n.default_locale = :"en-US" # I18n.fallbacks = I18n::Locale::Fallbacks.new(:"de-AT" => :"de-DE") # I18n.fallbacks[:"de-AT"] # => [:"de-AT", :"de-DE", :de, :"en-US", :en] # # # using a custom locale as default fallback locale # # I18n.fallbacks = I18n::Locale::Fallbacks.new(:"en-GB", :"de-AT" => :de, :"de-CH" => :de) # I18n.fallbacks[:"de-AT"] # => [:"de-AT", :de, :"en-GB", :en] # I18n.fallbacks[:"de-CH"] # => [:"de-CH", :de, :"en-GB", :en] # # # mapping fallbacks to an existing instance # # # people speaking Catalan also speak Spanish as spoken in Spain # fallbacks = I18n.fallbacks # fallbacks.map(:ca => :"es-ES") # fallbacks[:ca] # => [:ca, :"es-ES", :es, :"en-US", :en] # # # people speaking Arabian as spoken in Palestine also speak Hebrew as spoken in Israel # fallbacks.map(:"ar-PS" => :"he-IL") # fallbacks[:"ar-PS"] # => [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en] # fallbacks[:"ar-EG"] # => [:"ar-EG", :ar, :"en-US", :en] # # # people speaking Sami as spoken in Finnland also speak Swedish and Finnish as spoken in Finnland # fallbacks.map(:sms => [:"se-FI", :"fi-FI"]) # fallbacks[:sms] # => [:sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en] module I18n module Locale class Fallbacks < Hash def initialize(*mappings) @map = {} map(mappings.pop) if mappings.last.is_a?(Hash) self.defaults = mappings.empty? ? [I18n.default_locale.to_sym] : mappings end def defaults=(defaults) @defaults = defaults.map { |default| compute(default, false) }.flatten end attr_reader :defaults def [](locale) raise InvalidLocale.new(locale) if locale.nil? locale = locale.to_sym super || store(locale, compute(locale)) end def map(mappings) mappings.each do |from, to| from, to = from.to_sym, Array(to) to.each do |_to| @map[from] ||= [] @map[from] << _to.to_sym end end end protected def compute(tags, include_defaults = true, exclude = []) result = Array(tags).collect do |tag| tags = I18n::Locale::Tag.tag(tag).self_and_parents.map! { |t| t.to_sym } - exclude tags.each { |_tag| tags += compute(@map[_tag], false, exclude + tags) if @map[_tag] } tags end.flatten result.push(*defaults) if include_defaults result.uniq.compact end end end end i18n-0.7.0/lib/i18n/locale/tag.rb0000644000004100000410000000145212461054500016210 0ustar www-datawww-data# encoding: utf-8 module I18n module Locale module Tag autoload :Parents, 'i18n/locale/tag/parents' autoload :Rfc4646, 'i18n/locale/tag/rfc4646' autoload :Simple, 'i18n/locale/tag/simple' class << self # Returns the current locale tag implementation. Defaults to +I18n::Locale::Tag::Simple+. def implementation @@implementation ||= Simple end # Sets the current locale tag implementation. Use this to set a different locale tag implementation. def implementation=(implementation) @@implementation = implementation end # Factory method for locale tags. Delegates to the current locale tag implementation. def tag(tag) implementation.tag(tag) end end end end end i18n-0.7.0/lib/i18n/locale/tag/0000755000004100000410000000000012461054500015661 5ustar www-datawww-datai18n-0.7.0/lib/i18n/locale/tag/parents.rb0000644000004100000410000000074412461054500017667 0ustar www-datawww-datamodule I18n module Locale module Tag module Parents def parent @parent ||= begin segs = to_a.compact segs.length > 1 ? self.class.tag(*segs[0..(segs.length-2)].join('-')) : nil end end def self_and_parents @self_and_parents ||= [self] + parents end def parents @parents ||= ([parent] + (parent ? parent.parents : [])).compact end end end end end i18n-0.7.0/lib/i18n/locale/tag/simple.rb0000644000004100000410000000124012461054500017474 0ustar www-datawww-data# Simple Locale tag implementation that computes subtags by simply splitting # the locale tag at '-' occurences. module I18n module Locale module Tag class Simple class << self def tag(tag) new(tag) end end include Parents attr_reader :tag def initialize(*tag) @tag = tag.join('-').to_sym end def subtags @subtags = tag.to_s.split('-').map { |subtag| subtag.to_s } end def to_sym tag end def to_s tag.to_s end def to_a subtags end end end end end i18n-0.7.0/lib/i18n/locale/tag/rfc4646.rb0000644000004100000410000000466312461054500017315 0ustar www-datawww-data# RFC 4646/47 compliant Locale tag implementation that parses locale tags to # subtags such as language, script, region, variant etc. # # For more information see by http://en.wikipedia.org/wiki/IETF_language_tag # # Rfc4646::Parser does not implement grandfathered tags. module I18n module Locale module Tag RFC4646_SUBTAGS = [ :language, :script, :region, :variant, :extension, :privateuse, :grandfathered ] RFC4646_FORMATS = { :language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase } class Rfc4646 < Struct.new(*RFC4646_SUBTAGS) class << self # Parses the given tag and returns a Tag instance if it is valid. # Returns false if the given tag is not valid according to RFC 4646. def tag(tag) matches = parser.match(tag) new(*matches) if matches end def parser @@parser ||= Rfc4646::Parser end def parser=(parser) @@parser = parser end end include Parents RFC4646_FORMATS.each do |name, format| define_method(name) { self[name].send(format) unless self[name].nil? } end def to_sym to_s.to_sym end def to_s @tag ||= to_a.compact.join("-") end def to_a members.collect { |attr| self.send(attr) } end module Parser PATTERN = %r{\A(?: ([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language (?:-([a-z]{4}))? # script (?:-([a-z]{2}|\d{3}))? # region (?:-([0-9a-z]{5,8}|\d[0-9a-z]{3}))* # variant (?:-([0-9a-wyz](?:-[0-9a-z]{2,8})+))* # extension (?:-(x(?:-[0-9a-z]{1,8})+))?| # privateuse subtag (x(?:-[0-9a-z]{1,8})+)| # privateuse tag /* ([a-z]{1,3}(?:-[0-9a-z]{2,8}){1,2}) */ # grandfathered )\z}xi class << self def match(tag) c = PATTERN.match(tag.to_s).captures c[0..4] << (c[5].nil? ? c[6] : c[5]) << c[7] # TODO c[7] is grandfathered, throw a NotImplemented exception here? rescue false end end end end end end end i18n-0.7.0/lib/i18n.rb0000644000004100000410000003135412461054500014202 0ustar www-datawww-datarequire 'i18n/version' require 'i18n/exceptions' require 'i18n/interpolate/ruby' module I18n autoload :Backend, 'i18n/backend' autoload :Config, 'i18n/config' autoload :Gettext, 'i18n/gettext' autoload :Locale, 'i18n/locale' autoload :Tests, 'i18n/tests' RESERVED_KEYS = [:scope, :default, :separator, :resolve, :object, :fallback, :format, :cascade, :throw, :raise] RESERVED_KEYS_PATTERN = /%\{(#{RESERVED_KEYS.join("|")})\}/ extend(Module.new { # Gets I18n configuration object. def config Thread.current[:i18n_config] ||= I18n::Config.new end # Sets I18n configuration object. def config=(value) Thread.current[:i18n_config] = value end # Write methods which delegates to the configuration object %w(locale backend default_locale available_locales default_separator exception_handler load_path enforce_available_locales).each do |method| module_eval <<-DELEGATORS, __FILE__, __LINE__ + 1 def #{method} config.#{method} end def #{method}=(value) config.#{method} = (value) end DELEGATORS end # Tells the backend to reload translations. Used in situations like the # Rails development environment. Backends can implement whatever strategy # is useful. def reload! config.clear_available_locales_set config.backend.reload! end # Translates, pluralizes and interpolates a given key using a given locale, # scope, and default, as well as interpolation values. # # *LOOKUP* # # Translation data is organized as a nested hash using the upper-level keys # as namespaces. E.g., ActionView ships with the translation: # :date => {:formats => {:short => "%b %d"}}. # # Translations can be looked up at any level of this hash using the key argument # and the scope option. E.g., in this example I18n.t :date # returns the whole translations hash {:formats => {:short => "%b %d"}}. # # Key can be either a single key or a dot-separated key (both Strings and Symbols # work). E.g., the short format can be looked up using both: # I18n.t 'date.formats.short' # I18n.t :'date.formats.short' # # Scope can be either a single key, a dot-separated key or an array of keys # or dot-separated keys. Keys and scopes can be combined freely. So these # examples will all look up the same short date format: # I18n.t 'date.formats.short' # I18n.t 'formats.short', :scope => 'date' # I18n.t 'short', :scope => 'date.formats' # I18n.t 'short', :scope => %w(date formats) # # *INTERPOLATION* # # Translations can contain interpolation variables which will be replaced by # values passed to #translate as part of the options hash, with the keys matching # the interpolation variable names. # # E.g., with a translation :foo => "foo %{bar}" the option # value for the key +bar+ will be interpolated into the translation: # I18n.t :foo, :bar => 'baz' # => 'foo baz' # # *PLURALIZATION* # # Translation data can contain pluralized translations. Pluralized translations # are arrays of singluar/plural versions of translations like ['Foo', 'Foos']. # # Note that I18n::Backend::Simple only supports an algorithm for English # pluralization rules. Other algorithms can be supported by custom backends. # # This returns the singular version of a pluralized translation: # I18n.t :foo, :count => 1 # => 'Foo' # # These both return the plural version of a pluralized translation: # I18n.t :foo, :count => 0 # => 'Foos' # I18n.t :foo, :count => 2 # => 'Foos' # # The :count option can be used both for pluralization and interpolation. # E.g., with the translation # :foo => ['%{count} foo', '%{count} foos'], count will # be interpolated to the pluralized translation: # I18n.t :foo, :count => 1 # => '1 foo' # # *DEFAULTS* # # This returns the translation for :foo or default if no translation was found: # I18n.t :foo, :default => 'default' # # This returns the translation for :foo or the translation for :bar if no # translation for :foo was found: # I18n.t :foo, :default => :bar # # Returns the translation for :foo or the translation for :bar # or default if no translations for :foo and :bar were found. # I18n.t :foo, :default => [:bar, 'default'] # # *BULK LOOKUP* # # This returns an array with the translations for :foo and :bar. # I18n.t [:foo, :bar] # # Can be used with dot-separated nested keys: # I18n.t [:'baz.foo', :'baz.bar'] # # Which is the same as using a scope option: # I18n.t [:foo, :bar], :scope => :baz # # *LAMBDAS* # # Both translations and defaults can be given as Ruby lambdas. Lambdas will be # called and passed the key and options. # # E.g. assuming the key :salutation resolves to: # lambda { |key, options| options[:gender] == 'm' ? "Mr. %{options[:name]}" : "Mrs. %{options[:name]}" } # # Then I18n.t(:salutation, :gender => 'w', :name => 'Smith') will result in "Mrs. Smith". # # It is recommended to use/implement lambdas in an "idempotent" way. E.g. when # a cache layer is put in front of I18n.translate it will generate a cache key # from the argument values passed to #translate. Therefor your lambdas should # always return the same translations/values per unique combination of argument # values. def translate(*args) options = args.last.is_a?(Hash) ? args.pop.dup : {} key = args.shift backend = config.backend locale = options.delete(:locale) || config.locale handling = options.delete(:throw) && :throw || options.delete(:raise) && :raise # TODO deprecate :raise enforce_available_locales!(locale) raise I18n::ArgumentError if key.is_a?(String) && key.empty? result = catch(:exception) do if key.is_a?(Array) key.map { |k| backend.translate(locale, k, options) } else backend.translate(locale, key, options) end end result.is_a?(MissingTranslation) ? handle_exception(handling, result, locale, key, options) : result end alias :t :translate # Wrapper for translate that adds :raise => true. With # this option, if no translation is found, it will raise I18n::MissingTranslationData def translate!(key, options={}) translate(key, options.merge(:raise => true)) end alias :t! :translate! # Returns true if a translation exists for a given key, otherwise returns false. def exists?(key, locale = config.locale) raise I18n::ArgumentError if key.is_a?(String) && key.empty? config.backend.exists?(locale, key) end # Transliterates UTF-8 characters to ASCII. By default this method will # transliterate only Latin strings to an ASCII approximation: # # I18n.transliterate("Ærøskøbing") # # => "AEroskobing" # # I18n.transliterate("日本語") # # => "???" # # It's also possible to add support for per-locale transliterations. I18n # expects transliteration rules to be stored at # i18n.transliterate.rule. # # Transliteration rules can either be a Hash or a Proc. Procs must accept a # single string argument. Hash rules inherit the default transliteration # rules, while Procs do not. # # *Examples* # # Setting a Hash in .yml: # # i18n: # transliterate: # rule: # ü: "ue" # ö: "oe" # # Setting a Hash using Ruby: # # store_translations(:de, :i18n => { # :transliterate => { # :rule => { # "ü" => "ue", # "ö" => "oe" # } # } # ) # # Setting a Proc: # # translit = lambda {|string| MyTransliterator.transliterate(string) } # store_translations(:xx, :i18n => {:transliterate => {:rule => translit}) # # Transliterating strings: # # I18n.locale = :en # I18n.transliterate("Jürgen") # => "Jurgen" # I18n.locale = :de # I18n.transliterate("Jürgen") # => "Juergen" # I18n.transliterate("Jürgen", :locale => :en) # => "Jurgen" # I18n.transliterate("Jürgen", :locale => :de) # => "Juergen" def transliterate(*args) options = args.pop.dup if args.last.is_a?(Hash) key = args.shift locale = options && options.delete(:locale) || config.locale handling = options && (options.delete(:throw) && :throw || options.delete(:raise) && :raise) replacement = options && options.delete(:replacement) enforce_available_locales!(locale) config.backend.transliterate(locale, key, replacement) rescue I18n::ArgumentError => exception handle_exception(handling, exception, locale, key, options || {}) end # Localizes certain objects, such as dates and numbers to local formatting. def localize(object, options = nil) options = options ? options.dup : {} locale = options.delete(:locale) || config.locale format = options.delete(:format) || :default enforce_available_locales!(locale) config.backend.localize(locale, object, format, options) end alias :l :localize # Executes block with given I18n.locale set. def with_locale(tmp_locale = nil) if tmp_locale current_locale = self.locale self.locale = tmp_locale end yield ensure self.locale = current_locale if tmp_locale end # Merges the given locale, key and scope into a single array of keys. # Splits keys that contain dots into multiple keys. Makes sure all # keys are Symbols. def normalize_keys(locale, key, scope, separator = nil) separator ||= I18n.default_separator keys = [] keys.concat normalize_key(locale, separator) keys.concat normalize_key(scope, separator) keys.concat normalize_key(key, separator) keys end # Returns true when the passed locale, which can be either a String or a # Symbol, is in the list of available locales. Returns false otherwise. def locale_available?(locale) I18n.config.available_locales_set.include?(locale) end # Raises an InvalidLocale exception when the passed locale is not available. def enforce_available_locales!(locale) if config.enforce_available_locales raise I18n::InvalidLocale.new(locale) if !locale_available?(locale) end end private # Any exceptions thrown in translate will be sent to the @@exception_handler # which can be a Symbol, a Proc or any other Object unless they're forced to # be raised or thrown (MissingTranslation). # # If exception_handler is a Symbol then it will simply be sent to I18n as # a method call. A Proc will simply be called. In any other case the # method #call will be called on the exception_handler object. # # Examples: # # I18n.exception_handler = :custom_exception_handler # this is the default # I18n.custom_exception_handler(exception, locale, key, options) # will be called like this # # I18n.exception_handler = lambda { |*args| ... } # a lambda # I18n.exception_handler.call(exception, locale, key, options) # will be called like this # # I18n.exception_handler = I18nExceptionHandler.new # an object # I18n.exception_handler.call(exception, locale, key, options) # will be called like this def handle_exception(handling, exception, locale, key, options) case handling when :raise raise exception.respond_to?(:to_exception) ? exception.to_exception : exception when :throw throw :exception, exception else case handler = options[:exception_handler] || config.exception_handler when Symbol send(handler, exception, locale, key, options) else handler.call(exception, locale, key, options) end end end def normalize_key(key, separator) normalized_key_cache[separator][key] ||= case key when Array key.map { |k| normalize_key(k, separator) }.flatten else keys = key.to_s.split(separator) keys.delete('') keys.map! { |k| k.to_sym } keys end end def normalized_key_cache @normalized_key_cache ||= Hash.new { |h,k| h[k] = {} } end }) end i18n-0.7.0/gemfiles/0000755000004100000410000000000012461054500014115 5ustar www-datawww-datai18n-0.7.0/gemfiles/Gemfile.rails-3.2.x0000644000004100000410000000020412461054500017263 0ustar www-datawww-datasource 'https://rubygems.org' gemspec :path => '..' gem 'activesupport', '~> 3.2.0' gem 'mocha' gem 'test_declarative' gem 'rake' i18n-0.7.0/gemfiles/Gemfile.rails-3.2.x.lock0000644000004100000410000000063412461054500020221 0ustar www-datawww-dataPATH remote: .. specs: i18n (0.7.0) GEM remote: https://rubygems.org/ specs: activesupport (3.2.21) i18n (~> 0.6, >= 0.6.4) multi_json (~> 1.0) metaclass (0.0.4) mocha (1.1.0) metaclass (~> 0.0.1) multi_json (1.10.1) rake (10.4.2) test_declarative (0.0.5) PLATFORMS ruby DEPENDENCIES activesupport (~> 3.2.0) i18n! mocha rake test_declarative i18n-0.7.0/gemfiles/Gemfile.rails-4.2.x.lock0000644000004100000410000000111112461054500020211 0ustar www-datawww-dataPATH remote: .. specs: i18n (0.7.0) GEM remote: https://rubygems.org/ specs: activesupport (4.2.0.rc3) i18n (>= 0.7.0.beta1, < 0.8) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.1) tzinfo (~> 1.1) json (1.8.1) metaclass (0.0.4) minitest (5.5.0) mocha (1.1.0) metaclass (~> 0.0.1) rake (10.4.2) test_declarative (0.0.5) thread_safe (0.3.4) tzinfo (1.2.2) thread_safe (~> 0.1) PLATFORMS ruby DEPENDENCIES activesupport (~> 4.2.0.rc3) i18n! mocha rake test_declarative i18n-0.7.0/gemfiles/Gemfile.rails-master.lock0000644000004100000410000000127412461054500020745 0ustar www-datawww-dataGIT remote: git://github.com/rails/rails.git revision: fe46f009be1ece58e45abc51195e2381a71bd023 branch: master specs: activesupport (5.0.0.alpha) i18n (>= 0.7.0.beta1, < 0.8) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.1) tzinfo (~> 1.1) PATH remote: .. specs: i18n (0.7.0) GEM remote: https://rubygems.org/ specs: json (1.8.1) metaclass (0.0.4) minitest (5.5.0) mocha (1.1.0) metaclass (~> 0.0.1) rake (10.4.2) test_declarative (0.0.5) thread_safe (0.3.4) tzinfo (1.2.2) thread_safe (~> 0.1) PLATFORMS ruby DEPENDENCIES activesupport! i18n! mocha rake test_declarative i18n-0.7.0/gemfiles/Gemfile.rails-master0000644000004100000410000000024112461054500020007 0ustar www-datawww-datasource 'https://rubygems.org' gemspec :path => '..' gem 'activesupport', github: 'rails/rails', branch: 'master' gem 'mocha' gem 'test_declarative' gem 'rake' i18n-0.7.0/gemfiles/Gemfile.rails-4.1.x0000644000004100000410000000020412461054500017263 0ustar www-datawww-datasource 'https://rubygems.org' gemspec :path => '..' gem 'activesupport', '~> 4.1.0' gem 'mocha' gem 'test_declarative' gem 'rake' i18n-0.7.0/gemfiles/Gemfile.rails-4.1.x.lock0000644000004100000410000000107412461054500020220 0ustar www-datawww-dataPATH remote: .. specs: i18n (0.7.0) GEM remote: https://rubygems.org/ specs: activesupport (4.1.8) i18n (~> 0.6, >= 0.6.9) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.1) tzinfo (~> 1.1) json (1.8.1) metaclass (0.0.4) minitest (5.5.0) mocha (1.1.0) metaclass (~> 0.0.1) rake (10.4.2) test_declarative (0.0.5) thread_safe (0.3.4) tzinfo (1.2.2) thread_safe (~> 0.1) PLATFORMS ruby DEPENDENCIES activesupport (~> 4.1.0) i18n! mocha rake test_declarative i18n-0.7.0/gemfiles/Gemfile.rails-4.2.x0000644000004100000410000000021012461054500017261 0ustar www-datawww-datasource 'https://rubygems.org' gemspec :path => '..' gem 'activesupport', '~> 4.2.0.rc3' gem 'mocha' gem 'test_declarative' gem 'rake' i18n-0.7.0/gemfiles/Gemfile.rails-4.0.x.lock0000644000004100000410000000105112461054500020212 0ustar www-datawww-dataPATH remote: .. specs: i18n (0.7.0) GEM remote: https://rubygems.org/ specs: activesupport (4.0.12) i18n (~> 0.6, >= 0.6.9) minitest (~> 4.2) multi_json (~> 1.3) thread_safe (~> 0.1) tzinfo (~> 0.3.37) metaclass (0.0.4) minitest (4.7.5) mocha (1.1.0) metaclass (~> 0.0.1) multi_json (1.10.1) rake (10.4.2) test_declarative (0.0.5) thread_safe (0.3.4) tzinfo (0.3.42) PLATFORMS ruby DEPENDENCIES activesupport (~> 4.0.0) i18n! mocha rake test_declarative i18n-0.7.0/gemfiles/Gemfile.rails-4.0.x0000644000004100000410000000020412461054500017262 0ustar www-datawww-datasource 'https://rubygems.org' gemspec :path => '..' gem 'activesupport', '~> 4.0.0' gem 'mocha' gem 'test_declarative' gem 'rake' i18n-0.7.0/metadata.yml0000644000004100000410000000761612461054500014637 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: i18n version: !ruby/object:Gem::Version version: 0.7.0 platform: ruby authors: - Sven Fuchs - Joshua Harvey - Matt Aimonetti - Stephan Soller - Saimon Moore autorequire: bindir: bin cert_chain: [] date: 2014-12-19 00:00:00.000000000 Z dependencies: [] description: New wave Internationalization support for Ruby. email: rails-i18n@googlegroups.com executables: [] extensions: [] extra_rdoc_files: [] files: - MIT-LICENSE - README.md - gemfiles/Gemfile.rails-3.2.x - gemfiles/Gemfile.rails-3.2.x.lock - gemfiles/Gemfile.rails-4.0.x - gemfiles/Gemfile.rails-4.0.x.lock - gemfiles/Gemfile.rails-4.1.x - gemfiles/Gemfile.rails-4.1.x.lock - gemfiles/Gemfile.rails-4.2.x - gemfiles/Gemfile.rails-4.2.x.lock - gemfiles/Gemfile.rails-master - gemfiles/Gemfile.rails-master.lock - lib/i18n.rb - lib/i18n/backend.rb - lib/i18n/backend/base.rb - lib/i18n/backend/cache.rb - lib/i18n/backend/cascade.rb - lib/i18n/backend/chain.rb - lib/i18n/backend/fallbacks.rb - lib/i18n/backend/flatten.rb - lib/i18n/backend/gettext.rb - lib/i18n/backend/interpolation_compiler.rb - lib/i18n/backend/key_value.rb - lib/i18n/backend/memoize.rb - lib/i18n/backend/metadata.rb - lib/i18n/backend/pluralization.rb - lib/i18n/backend/simple.rb - lib/i18n/backend/transliterator.rb - lib/i18n/config.rb - lib/i18n/core_ext/hash.rb - lib/i18n/core_ext/kernel/suppress_warnings.rb - lib/i18n/core_ext/string/interpolate.rb - lib/i18n/exceptions.rb - lib/i18n/gettext.rb - lib/i18n/gettext/helpers.rb - lib/i18n/gettext/po_parser.rb - lib/i18n/interpolate/ruby.rb - lib/i18n/locale.rb - lib/i18n/locale/fallbacks.rb - lib/i18n/locale/tag.rb - lib/i18n/locale/tag/parents.rb - lib/i18n/locale/tag/rfc4646.rb - lib/i18n/locale/tag/simple.rb - lib/i18n/tests.rb - lib/i18n/tests/basics.rb - lib/i18n/tests/defaults.rb - lib/i18n/tests/interpolation.rb - lib/i18n/tests/link.rb - lib/i18n/tests/localization.rb - lib/i18n/tests/localization/date.rb - lib/i18n/tests/localization/date_time.rb - lib/i18n/tests/localization/procs.rb - lib/i18n/tests/localization/time.rb - lib/i18n/tests/lookup.rb - lib/i18n/tests/pluralization.rb - lib/i18n/tests/procs.rb - lib/i18n/version.rb - test/api/all_features_test.rb - test/api/cascade_test.rb - test/api/chain_test.rb - test/api/fallbacks_test.rb - test/api/key_value_test.rb - test/api/memoize_test.rb - test/api/override_test.rb - test/api/pluralization_test.rb - test/api/simple_test.rb - test/backend/cache_test.rb - test/backend/cascade_test.rb - test/backend/chain_test.rb - test/backend/exceptions_test.rb - test/backend/fallbacks_test.rb - test/backend/interpolation_compiler_test.rb - test/backend/key_value_test.rb - test/backend/memoize_test.rb - test/backend/metadata_test.rb - test/backend/pluralization_test.rb - test/backend/simple_test.rb - test/backend/transliterator_test.rb - test/core_ext/hash_test.rb - test/gettext/api_test.rb - test/gettext/backend_test.rb - test/i18n/exceptions_test.rb - test/i18n/interpolate_test.rb - test/i18n/load_path_test.rb - test/i18n_test.rb - test/locale/fallbacks_test.rb - test/locale/tag/rfc4646_test.rb - test/locale/tag/simple_test.rb - test/run_all.rb - test/test_data/locales/de.po - test/test_data/locales/en.rb - test/test_data/locales/en.yml - test/test_data/locales/invalid/empty.yml - test/test_data/locales/invalid/syntax.yml - test/test_data/locales/plurals.rb - test/test_helper.rb homepage: http://github.com/svenfuchs/i18n licenses: - MIT metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.9.3 required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: 1.3.5 requirements: [] rubyforge_project: "[none]" rubygems_version: 2.4.3 signing_key: specification_version: 4 summary: New wave Internationalization support for Ruby test_files: [] i18n-0.7.0/test/0000755000004100000410000000000012461054500013301 5ustar www-datawww-datai18n-0.7.0/test/core_ext/0000755000004100000410000000000012461054500015111 5ustar www-datawww-datai18n-0.7.0/test/core_ext/hash_test.rb0000644000004100000410000000155712461054500017430 0ustar www-datawww-datarequire 'test_helper' require 'i18n/core_ext/hash' class I18nCoreExtHashInterpolationTest < I18n::TestCase test "#deep_symbolize_keys" do hash = { 'foo' => { 'bar' => { 'baz' => 'bar' } } } expected = { :foo => { :bar => { :baz => 'bar' } } } assert_equal expected, hash.deep_symbolize_keys end test "#slice" do hash = { :foo => 'bar', :baz => 'bar' } expected = { :foo => 'bar' } assert_equal expected, hash.slice(:foo) end test "#except" do hash = { :foo => 'bar', :baz => 'bar' } expected = { :foo => 'bar' } assert_equal expected, hash.except(:baz) end test "#deep_merge!" do hash = { :foo => { :bar => { :baz => 'bar' } }, :baz => 'bar' } hash.deep_merge!(:foo => { :bar => { :baz => 'foo' } }) expected = { :foo => { :bar => { :baz => 'foo' } }, :baz => 'bar' } assert_equal expected, hash end end i18n-0.7.0/test/i18n_test.rb0000644000004100000410000003521312461054500015450 0ustar www-datawww-data# encoding: utf-8 require 'test_helper' class I18nTest < I18n::TestCase def setup super store_translations(:en, :currency => { :format => { :separator => '.', :delimiter => ',', } }) store_translations(:nl, :currency => { :format => { :separator => ',', :delimiter => '.', } }) end test "exposes its VERSION constant" do assert I18n::VERSION end test "uses the simple backend by default" do assert I18n.backend.is_a?(I18n::Backend::Simple) end test "can set the backend" do begin assert_nothing_raised { I18n.backend = self } assert_equal self, I18n.backend ensure I18n.backend = I18n::Backend::Simple.new end end test "uses :en as a default_locale by default" do assert_equal :en, I18n.default_locale end test "can set the default locale" do begin assert_nothing_raised { I18n.default_locale = 'de' } assert_equal :de, I18n.default_locale ensure I18n.default_locale = :en end end test "default_locale= doesn't ignore junk" do assert_raise(NoMethodError) { I18n.default_locale = Class } end test "raises an I18n::InvalidLocale exception when setting an unavailable default locale" do begin I18n.config.enforce_available_locales = true assert_raise(I18n::InvalidLocale) { I18n.default_locale = :klingon } ensure I18n.config.enforce_available_locales = false end end test "uses the default locale as a locale by default" do assert_equal I18n.default_locale, I18n.locale end test "sets the current locale to Thread.current" do assert_nothing_raised { I18n.locale = 'de' } assert_equal :de, I18n.locale assert_equal :de, Thread.current[:i18n_config].locale I18n.locale = :en end test "locale= doesn't ignore junk" do assert_raise(NoMethodError) { I18n.locale = Class } end test "raises an I18n::InvalidLocale exception when setting an unavailable locale" do begin I18n.config.enforce_available_locales = true assert_raise(I18n::InvalidLocale) { I18n.locale = :klingon } ensure I18n.config.enforce_available_locales = false end end test "can set the configuration object" do begin I18n.config = self assert_equal self, I18n.config assert_equal self, Thread.current[:i18n_config] ensure I18n.config = ::I18n::Config.new end end test "locale is not shared between configurations" do a = I18n::Config.new b = I18n::Config.new a.locale = :fr b.locale = :es assert_equal :fr, a.locale assert_equal :es, b.locale assert_equal :en, I18n.locale end test "other options are shared between configurations" do begin a = I18n::Config.new b = I18n::Config.new a.default_locale = :fr b.default_locale = :es assert_equal :es, a.default_locale assert_equal :es, b.default_locale assert_equal :es, I18n.default_locale ensure I18n.default_locale = :en end end test "uses a dot as a default_separator by default" do assert_equal '.', I18n.default_separator end test "can set the default_separator" do begin assert_nothing_raised { I18n.default_separator = "\001" } ensure I18n.default_separator = '.' end end test "normalize_keys normalizes given locale, keys and scope to an array of single-key symbols" do assert_equal [:en, :foo, :bar], I18n.normalize_keys(:en, :bar, :foo) assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, :'baz.buz', :'foo.bar') assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, 'baz.buz', 'foo.bar') assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, %w(baz buz), %w(foo bar)) assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, [:baz, :buz], [:foo, :bar]) end test "normalize_keys discards empty keys" do assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, :'baz..buz', :'foo..bar') assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, :'baz......buz', :'foo......bar') assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, ['baz', nil, '', 'buz'], ['foo', nil, '', 'bar']) end test "normalize_keys uses a given separator" do assert_equal [:en, :foo, :bar, :baz, :buz], I18n.normalize_keys(:en, :'baz|buz', :'foo|bar', '|') end test "can set the exception_handler" do begin previous_exception_handler = I18n.exception_handler assert_nothing_raised { I18n.exception_handler = :custom_exception_handler } ensure I18n.exception_handler = previous_exception_handler end end test "uses a custom exception handler set to I18n.exception_handler" do begin previous_exception_handler = I18n.exception_handler I18n.exception_handler = :custom_exception_handler I18n.expects(:custom_exception_handler) I18n.translate :bogus ensure I18n.exception_handler = previous_exception_handler end end test "uses a custom exception handler passed as an option" do I18n.expects(:custom_exception_handler) I18n.translate(:bogus, :exception_handler => :custom_exception_handler) end test "delegates translate calls to the backend" do I18n.backend.expects(:translate).with('de', :foo, {}) I18n.translate :foo, :locale => 'de' end test "delegates localize calls to the backend" do I18n.backend.expects(:localize).with('de', :whatever, :default, {}) I18n.localize :whatever, :locale => 'de' end test "translate given no locale uses the current locale" do I18n.backend.expects(:translate).with(:en, :foo, {}) I18n.translate :foo end test "translate works with nested symbol keys" do assert_equal ".", I18n.t(:'currency.format.separator') end test "translate works with nested string keys" do assert_equal ".", I18n.t('currency.format.separator') end test "translate with an array as a scope works" do assert_equal ".", I18n.t(:separator, :scope => %w(currency format)) end test "translate with an array containing dot separated strings as a scope works" do assert_equal ".", I18n.t(:separator, :scope => ['currency.format']) end test "translate with an array of keys and a dot separated string as a scope works" do assert_equal [".", ","], I18n.t(%w(separator delimiter), :scope => 'currency.format') end test "translate with an array of dot separated keys and a scope works" do assert_equal [".", ","], I18n.t(%w(format.separator format.delimiter), :scope => 'currency') end # def test_translate_given_no_args_raises_missing_translation_data # assert_equal "translation missing: en, no key", I18n.t # end test "translate given a bogus key returns an error message" do assert_equal "translation missing: en.bogus", I18n.t(:bogus) end test "translate given an empty string as a key raises an I18n::ArgumentError" do assert_raise(I18n::ArgumentError) { I18n.t("") } end test "translate given an unavailable locale rases an I18n::InvalidLocale" do begin I18n.config.enforce_available_locales = true assert_raise(I18n::InvalidLocale) { I18n.t(:foo, :locale => 'klingon') } ensure I18n.config.enforce_available_locales = false end end test "available_locales can be replaced at runtime" do begin I18n.config.enforce_available_locales = true assert_raise(I18n::InvalidLocale) { I18n.t(:foo, :locale => 'klingon') } old_locales, I18n.config.available_locales = I18n.config.available_locales, [:klingon] I18n.t(:foo, :locale => 'klingon') ensure I18n.config.enforce_available_locales = false I18n.config.available_locales = old_locales end end test "available_locales_set should return a set" do assert_equal Set, I18n.config.available_locales_set.class assert_equal I18n.config.available_locales.size * 2, I18n.config.available_locales_set.size end test "exists? given an existing key will return true" do assert_equal true, I18n.exists?(:currency) end test "exists? given a non-existing key will return false" do assert_equal false, I18n.exists?(:bogus) end test "exists? given an existing dot-separated key will return true" do assert_equal true, I18n.exists?('currency.format.delimiter') end test "exists? given a non-existing dot-separated key will return false" do assert_equal false, I18n.exists?('currency.format.bogus') end test "exists? given an existing key and an existing locale will return true" do assert_equal true, I18n.exists?(:currency, :nl) end test "exists? given a non-existing key and an existing locale will return false" do assert_equal false, I18n.exists?(:bogus, :nl) end test "localize given nil raises an I18n::ArgumentError" do assert_raise(I18n::ArgumentError) { I18n.l nil } end test "localize given an Object raises an I18n::ArgumentError" do assert_raise(I18n::ArgumentError) { I18n.l Object.new } end test "localize given an unavailable locale rases an I18n::InvalidLocale" do begin I18n.config.enforce_available_locales = true assert_raise(I18n::InvalidLocale) { I18n.l(Time.now, :locale => 'klingon') } ensure I18n.config.enforce_available_locales = false end end test "can use a lambda as an exception handler" do begin previous_exception_handler = I18n.exception_handler I18n.exception_handler = Proc.new { |exception, locale, key, options| key } assert_equal :test_proc_handler, I18n.translate(:test_proc_handler) ensure I18n.exception_handler = previous_exception_handler end end test "can use an object responding to #call as an exception handler" do begin previous_exception_handler = I18n.exception_handler I18n.exception_handler = Class.new do def call(exception, locale, key, options); key; end end.new assert_equal :test_proc_handler, I18n.translate(:test_proc_handler) ensure I18n.exception_handler = previous_exception_handler end end test "I18n.with_locale temporarily sets the given locale" do store_translations(:en, :foo => 'Foo in :en') store_translations(:de, :foo => 'Foo in :de') store_translations(:pl, :foo => 'Foo in :pl') I18n.with_locale { assert_equal [:en, 'Foo in :en'], [I18n.locale, I18n.t(:foo)] } I18n.with_locale(:de) { assert_equal [:de, 'Foo in :de'], [I18n.locale, I18n.t(:foo)] } I18n.with_locale(:pl) { assert_equal [:pl, 'Foo in :pl'], [I18n.locale, I18n.t(:foo)] } I18n.with_locale(:en) { assert_equal [:en, 'Foo in :en'], [I18n.locale, I18n.t(:foo)] } assert_equal I18n.default_locale, I18n.locale end test "I18n.with_locale resets the locale in case of errors" do assert_raise(I18n::ArgumentError) { I18n.with_locale(:pl) { raise I18n::ArgumentError } } assert_equal I18n.default_locale, I18n.locale end test "I18n.translitarate handles I18n::ArgumentError exception" do I18n::Backend::Transliterator.stubs(:get).raises(I18n::ArgumentError) I18n.exception_handler.expects(:call).raises(I18n::ArgumentError) assert_raise(I18n::ArgumentError) { I18n.transliterate("ąćó") } end test "I18n.translitarate raises I18n::ArgumentError exception" do I18n::Backend::Transliterator.stubs(:get).raises(I18n::ArgumentError) I18n.exception_handler.expects(:call).never assert_raise(I18n::ArgumentError) { I18n.transliterate("ąćó", :raise => true) } end test "transliterate given an unavailable locale rases an I18n::InvalidLocale" do begin I18n.config.enforce_available_locales = true assert_raise(I18n::InvalidLocale) { I18n.transliterate('string', :locale => 'klingon') } ensure I18n.config.enforce_available_locales = false end end test "I18n.locale_available? returns true when the passed locale is available" do I18n.available_locales = [:en, :de] assert_equal true, I18n.locale_available?(:de) end test "I18n.locale_available? returns true when the passed locale is a string and is available" do I18n.available_locales = [:en, :de] assert_equal true, I18n.locale_available?('de') end test "I18n.locale_available? returns false when the passed locale is unavailable" do assert_equal false, I18n.locale_available?(:klingon) end test "I18n.enforce_available_locales! raises an I18n::InvalidLocale when the passed locale is unavailable" do begin I18n.config.enforce_available_locales = true assert_raise(I18n::InvalidLocale) { I18n.enforce_available_locales!(:klingon) } ensure I18n.config.enforce_available_locales = false end end test "I18n.enforce_available_locales! does nothing when the passed locale is available" do I18n.available_locales = [:en, :de] begin I18n.config.enforce_available_locales = true assert_nothing_raised { I18n.enforce_available_locales!(:en) } ensure I18n.config.enforce_available_locales = false end end test "I18n.enforce_available_locales config can be set to false" do begin I18n.config.enforce_available_locales = false assert_equal false, I18n.config.enforce_available_locales ensure I18n.config.enforce_available_locales = false end end test 'I18n.reload! reloads the set of locales that are enforced' do begin # Clear the backend that affects the available locales and somehow can remain # set from the last running test. # For instance, it contains enough translations to cause a false positive with # this test when ran with --seed=50992 I18n.backend = I18n::Backend::Simple.new assert !I18n.available_locales.include?(:de), "Available locales should not include :de at this point" I18n.enforce_available_locales = true assert_raise(I18n::InvalidLocale) { I18n.default_locale = :de } assert_raise(I18n::InvalidLocale) { I18n.locale = :de } store_translations(:de, :foo => 'Foo in :de') assert_raise(I18n::InvalidLocale) { I18n.default_locale = :de } assert_raise(I18n::InvalidLocale) { I18n.locale = :de } I18n.reload! store_translations(:en, :foo => 'Foo in :en') store_translations(:de, :foo => 'Foo in :de') store_translations(:pl, :foo => 'Foo in :pl') assert I18n.available_locales.include?(:de), ":de should now be allowed" assert I18n.available_locales.include?(:en), ":en should now be allowed" assert I18n.available_locales.include?(:pl), ":pl should now be allowed" assert_nothing_raised { I18n.default_locale = I18n.locale = :en } assert_nothing_raised { I18n.default_locale = I18n.locale = :de } assert_nothing_raised { I18n.default_locale = I18n.locale = :pl } ensure I18n.enforce_available_locales = false end end end i18n-0.7.0/test/i18n/0000755000004100000410000000000012461054500014060 5ustar www-datawww-datai18n-0.7.0/test/i18n/load_path_test.rb0000644000004100000410000000204712461054500017402 0ustar www-datawww-datarequire 'test_helper' class I18nLoadPathTest < I18n::TestCase def setup super I18n.locale = :en I18n.backend = I18n::Backend::Simple.new store_translations(:en, :foo => {:bar => 'bar', :baz => 'baz'}) end test "nested load paths do not break locale loading" do I18n.load_path = [[locales_dir + '/en.yml']] assert_equal "baz", I18n.t(:'foo.bar') end test "loading an empty yml file raises an InvalidLocaleData exception" do assert_raise I18n::InvalidLocaleData do I18n.load_path = [[locales_dir + '/invalid/empty.yml']] I18n.t(:'foo.bar', :default => "baz") end end test "loading an invalid yml file raises an InvalidLocaleData exception" do assert_raise I18n::InvalidLocaleData do I18n.load_path = [[locales_dir + '/invalid/syntax.yml']] I18n.t(:'foo.bar', :default => "baz") end end test "adding arrays of filenames to the load path does not break locale loading" do I18n.load_path << Dir[locales_dir + '/*.{rb,yml}'] assert_equal "baz", I18n.t(:'foo.bar') end end i18n-0.7.0/test/i18n/interpolate_test.rb0000644000004100000410000000706712461054500020004 0ustar www-datawww-datarequire 'test_helper' # thanks to Masao's String extensions, some tests taken from Masao's tests # http://github.com/mutoh/gettext/blob/edbbe1fa8238fa12c7f26f2418403015f0270e47/test/test_string.rb class I18nInterpolateTest < I18n::TestCase test "String interpolates a hash argument w/ named placeholders" do assert_equal "Masao Mutoh", I18n.interpolate("%{first} %{last}", :first => 'Masao', :last => 'Mutoh' ) end test "String interpolates a hash argument w/ named placeholders (reverse order)" do assert_equal "Mutoh, Masao", I18n.interpolate("%{last}, %{first}", :first => 'Masao', :last => 'Mutoh' ) end test "String interpolates named placeholders with sprintf syntax" do assert_equal "10, 43.4", I18n.interpolate("%d, %.1f", :integer => 10, :float => 43.4) end test "String interpolates named placeholders with sprintf syntax, does not recurse" do assert_equal "%s", I18n.interpolate("%{msg}", :msg => '%s', :not_translated => 'should not happen' ) end test "String interpolation does not replace anything when no placeholders are given" do assert_equal "aaa", I18n.interpolate("aaa", :num => 1) end test "String interpolation sprintf behaviour equals Ruby 1.9 behaviour" do assert_equal "1", I18n.interpolate("%d", :num => 1) assert_equal "0b1", I18n.interpolate("%#b", :num => 1) assert_equal "foo", I18n.interpolate("%s", :msg => "foo") assert_equal "1.000000", I18n.interpolate("%f", :num => 1.0) assert_equal " 1", I18n.interpolate("%3.0f", :num => 1.0) assert_equal "100.00", I18n.interpolate("%2.2f", :num => 100.0) assert_equal "0x64", I18n.interpolate("%#x", :num => 100.0) assert_raise(ArgumentError) { I18n.interpolate("%,d", :num => 100) } assert_raise(ArgumentError) { I18n.interpolate("%/d", :num => 100) } end test "String interpolation raises an I18n::MissingInterpolationArgument when the string has extra placeholders" do assert_raise(I18n::MissingInterpolationArgument) do # Ruby 1.9 msg: "key not found" I18n.interpolate("%{first} %{last}", :first => 'Masao') end end test "String interpolation does not raise when extra values were passed" do assert_nothing_raised do assert_equal "Masao Mutoh", I18n.interpolate("%{first} %{last}", :first => 'Masao', :last => 'Mutoh', :salutation => 'Mr.' ) end end test "% acts as escape character in String interpolation" do assert_equal "%{first}", I18n.interpolate("%%{first}", :first => 'Masao') assert_equal "% 1", I18n.interpolate("%% %d", :num => 1.0) assert_equal "%{num} %d", I18n.interpolate("%%{num} %%d", :num => 1) end def test_sprintf_mix_unformatted_and_formatted_named_placeholders assert_equal "foo 1.000000", I18n.interpolate("%{name} %f", :name => "foo", :num => 1.0) end end class I18nMissingInterpolationCustomHandlerTest < I18n::TestCase def setup super @old_handler = I18n.config.missing_interpolation_argument_handler I18n.config.missing_interpolation_argument_handler = lambda do |key, values, string| "missing key is #{key}, values are #{values.inspect}, given string is '#{string}'" end end def teardown I18n.config.missing_interpolation_argument_handler = @old_handler super end test "String interpolation can use custom missing interpolation handler" do assert_equal %|Masao missing key is last, values are {:first=>"Masao"}, given string is '%{first} %{last}'|, I18n.interpolate("%{first} %{last}", :first => 'Masao') end end i18n-0.7.0/test/i18n/exceptions_test.rb0000644000004100000410000000663712461054500017641 0ustar www-datawww-datarequire 'test_helper' class I18nExceptionsTest < I18n::TestCase def test_invalid_locale_stores_locale force_invalid_locale rescue I18n::ArgumentError => exception assert_nil exception.locale end test "passing an invalid locale raises an InvalidLocale exception" do force_invalid_locale do |exception| assert_equal 'nil is not a valid locale', exception.message end end test "MissingTranslationData exception stores locale, key and options" do force_missing_translation_data do |exception| assert_equal 'de', exception.locale assert_equal :foo, exception.key assert_equal({:scope => :bar}, exception.options) end end test "MissingTranslationData message contains the locale and scoped key" do force_missing_translation_data do |exception| assert_equal 'translation missing: de.bar.foo', exception.message end end test "InvalidPluralizationData stores entry and count" do force_invalid_pluralization_data do |exception| assert_equal [:bar], exception.entry assert_equal 1, exception.count end end test "InvalidPluralizationData message contains count and data" do force_invalid_pluralization_data do |exception| assert_equal 'translation data [:bar] can not be used with :count => 1', exception.message end end test "MissingInterpolationArgument stores key and string" do assert_raise(I18n::MissingInterpolationArgument) { force_missing_interpolation_argument } force_missing_interpolation_argument do |exception| assert_equal :bar, exception.key assert_equal "%{bar}", exception.string end end test "MissingInterpolationArgument message contains the missing and given arguments" do force_missing_interpolation_argument do |exception| assert_equal 'missing interpolation argument :bar in "%{bar}" ({:baz=>"baz"} given)', exception.message end end test "ReservedInterpolationKey stores key and string" do force_reserved_interpolation_key do |exception| assert_equal :scope, exception.key assert_equal "%{scope}", exception.string end end test "ReservedInterpolationKey message contains the reserved key" do force_reserved_interpolation_key do |exception| assert_equal 'reserved key :scope used in "%{scope}"', exception.message end end private def force_invalid_locale I18n.translate(:foo, :locale => nil) rescue I18n::ArgumentError => e block_given? ? yield(e) : raise(e) end def force_missing_translation_data(options = {}) store_translations('de', :bar => nil) I18n.translate(:foo, options.merge(:scope => :bar, :locale => :de)) rescue I18n::ArgumentError => e block_given? ? yield(e) : raise(e) end def force_invalid_pluralization_data store_translations('de', :foo => [:bar]) I18n.translate(:foo, :count => 1, :locale => :de) rescue I18n::ArgumentError => e block_given? ? yield(e) : raise(e) end def force_missing_interpolation_argument store_translations('de', :foo => "%{bar}") I18n.translate(:foo, :baz => 'baz', :locale => :de) rescue I18n::ArgumentError => e block_given? ? yield(e) : raise(e) end def force_reserved_interpolation_key store_translations('de', :foo => "%{scope}") I18n.translate(:foo, :baz => 'baz', :locale => :de) rescue I18n::ArgumentError => e block_given? ? yield(e) : raise(e) end end i18n-0.7.0/test/api/0000755000004100000410000000000012461054500014052 5ustar www-datawww-datai18n-0.7.0/test/api/simple_test.rb0000644000004100000410000000135312461054500016731 0ustar www-datawww-datarequire 'test_helper' class I18nSimpleBackendApiTest < I18n::TestCase class Backend < I18n::Backend::Simple include I18n::Backend::Pluralization end def setup I18n.backend = I18n::Backend::Simple.new super end include I18n::Tests::Basics include I18n::Tests::Defaults include I18n::Tests::Interpolation include I18n::Tests::Link include I18n::Tests::Lookup include I18n::Tests::Pluralization include I18n::Tests::Procs include I18n::Tests::Localization::Date include I18n::Tests::Localization::DateTime include I18n::Tests::Localization::Time include I18n::Tests::Localization::Procs test "make sure we use the Simple backend" do assert_equal I18n::Backend::Simple, I18n.backend.class end end i18n-0.7.0/test/api/key_value_test.rb0000644000004100000410000000126712461054500017430 0ustar www-datawww-datarequire 'test_helper' class I18nKeyValueApiTest < I18n::TestCase include I18n::Tests::Basics include I18n::Tests::Defaults include I18n::Tests::Interpolation include I18n::Tests::Link include I18n::Tests::Lookup include I18n::Tests::Pluralization # include Tests::Api::Procs include I18n::Tests::Localization::Date include I18n::Tests::Localization::DateTime include I18n::Tests::Localization::Time # include Tests::Api::Localization::Procs def setup I18n.backend = I18n::Backend::KeyValue.new({}) super end test "make sure we use the KeyValue backend" do assert_equal I18n::Backend::KeyValue, I18n.backend.class end end if I18n::TestCase.key_value? i18n-0.7.0/test/api/override_test.rb0000644000004100000410000000226012461054500017255 0ustar www-datawww-datarequire 'test_helper' class I18nOverrideTest < I18n::TestCase module OverrideInverse def translate(*args) super(*args).reverse end alias :t :translate end module OverrideSignature def translate(*args) args.first + args[1] end alias :t :translate end def setup super @I18n = I18n.dup @I18n.backend = I18n::Backend::Simple.new end test "make sure modules can overwrite I18n methods" do @I18n.extend OverrideInverse @I18n.backend.store_translations('en', :foo => 'bar') assert_equal 'rab', @I18n.translate(:foo, :locale => 'en') assert_equal 'rab', @I18n.t(:foo, :locale => 'en') assert_equal 'rab', @I18n.translate!(:foo, :locale => 'en') assert_equal 'rab', @I18n.t!(:foo, :locale => 'en') end test "make sure modules can overwrite I18n signature" do exception = catch(:exception) do @I18n.t('Hello', 'Welcome message on home page', :tokenize => true, :throw => true) end assert exception.message @I18n.extend OverrideSignature assert_equal 'HelloWelcome message on home page', @I18n.translate('Hello', 'Welcome message on home page', :tokenize => true) # tr8n example end end i18n-0.7.0/test/api/cascade_test.rb0000644000004100000410000000132012461054500017015 0ustar www-datawww-datarequire 'test_helper' class I18nCascadeApiTest < I18n::TestCase class Backend < I18n::Backend::Simple include I18n::Backend::Cascade end def setup I18n.backend = Backend.new super end include I18n::Tests::Basics include I18n::Tests::Defaults include I18n::Tests::Interpolation include I18n::Tests::Link include I18n::Tests::Lookup include I18n::Tests::Pluralization include I18n::Tests::Procs include I18n::Tests::Localization::Date include I18n::Tests::Localization::DateTime include I18n::Tests::Localization::Time include I18n::Tests::Localization::Procs test "make sure we use a backend with Cascade included" do assert_equal Backend, I18n.backend.class end end i18n-0.7.0/test/api/all_features_test.rb0000644000004100000410000000313012461054500020101 0ustar www-datawww-datarequire 'test_helper' begin require 'rubygems' require 'active_support' rescue LoadError puts "not testing with Cache enabled because active_support can not be found" end class I18nAllFeaturesApiTest < I18n::TestCase class Backend < I18n::Backend::Simple include I18n::Backend::Metadata include I18n::Backend::Cache include I18n::Backend::Cascade include I18n::Backend::Fallbacks include I18n::Backend::Pluralization include I18n::Backend::Memoize end def setup I18n.backend = I18n::Backend::Chain.new(Backend.new, I18n::Backend::Simple.new) I18n.cache_store = cache_store super end def teardown I18n.cache_store.clear if I18n.cache_store I18n.cache_store = nil super end def cache_store ActiveSupport::Cache.lookup_store(:memory_store) if cache_available? end def cache_available? defined?(ActiveSupport) && defined?(ActiveSupport::Cache) end include I18n::Tests::Basics include I18n::Tests::Defaults include I18n::Tests::Interpolation include I18n::Tests::Link include I18n::Tests::Lookup include I18n::Tests::Pluralization include I18n::Tests::Procs include I18n::Tests::Localization::Date include I18n::Tests::Localization::DateTime include I18n::Tests::Localization::Time include I18n::Tests::Localization::Procs test "make sure we use a Chain backend with an all features backend" do assert_equal I18n::Backend::Chain, I18n.backend.class assert_equal Backend, I18n.backend.backends.first.class end # links: test that keys stored on one backend can link to keys stored on another backend end i18n-0.7.0/test/api/memoize_test.rb0000644000004100000410000000276612461054500017116 0ustar www-datawww-datarequire 'test_helper' class I18nMemoizeBackendWithSimpleApiTest < I18n::TestCase include I18n::Tests::Basics include I18n::Tests::Defaults include I18n::Tests::Interpolation include I18n::Tests::Link include I18n::Tests::Lookup include I18n::Tests::Pluralization include I18n::Tests::Procs include I18n::Tests::Localization::Date include I18n::Tests::Localization::DateTime include I18n::Tests::Localization::Time include I18n::Tests::Localization::Procs class MemoizeBackend < I18n::Backend::Simple include I18n::Backend::Memoize end def setup I18n.backend = MemoizeBackend.new super end test "make sure we use the MemoizeBackend backend" do assert_equal MemoizeBackend, I18n.backend.class end end class I18nMemoizeBackendWithKeyValueApiTest < I18n::TestCase include I18n::Tests::Basics include I18n::Tests::Defaults include I18n::Tests::Interpolation include I18n::Tests::Link include I18n::Tests::Lookup include I18n::Tests::Pluralization include I18n::Tests::Localization::Date include I18n::Tests::Localization::DateTime include I18n::Tests::Localization::Time # include I18n::Tests::Procs # include I18n::Tests::Localization::Procs class MemoizeBackend < I18n::Backend::KeyValue include I18n::Backend::Memoize end def setup I18n.backend = MemoizeBackend.new({}) super end test "make sure we use the MemoizeBackend backend" do assert_equal MemoizeBackend, I18n.backend.class end end if I18n::TestCase.key_value? i18n-0.7.0/test/api/fallbacks_test.rb0000644000004100000410000000146212461054500017363 0ustar www-datawww-datarequire 'test_helper' class I18nFallbacksApiTest < I18n::TestCase class Backend < I18n::Backend::Simple include I18n::Backend::Fallbacks end def setup I18n.backend = Backend.new super end include I18n::Tests::Basics include I18n::Tests::Defaults include I18n::Tests::Interpolation include I18n::Tests::Link include I18n::Tests::Lookup include I18n::Tests::Pluralization include I18n::Tests::Procs include I18n::Tests::Localization::Date include I18n::Tests::Localization::DateTime include I18n::Tests::Localization::Time include I18n::Tests::Localization::Procs test "make sure we use a backend with Fallbacks included" do assert_equal Backend, I18n.backend.class end # links: test that keys stored on one backend can link to keys stored on another backend end i18n-0.7.0/test/api/pluralization_test.rb0000644000004100000410000000147612461054500020343 0ustar www-datawww-datarequire 'test_helper' class I18nPluralizationApiTest < I18n::TestCase class Backend < I18n::Backend::Simple include I18n::Backend::Pluralization end def setup I18n.backend = Backend.new super end include I18n::Tests::Basics include I18n::Tests::Defaults include I18n::Tests::Interpolation include I18n::Tests::Link include I18n::Tests::Lookup include I18n::Tests::Pluralization include I18n::Tests::Procs include I18n::Tests::Localization::Date include I18n::Tests::Localization::DateTime include I18n::Tests::Localization::Time include I18n::Tests::Localization::Procs test "make sure we use a backend with Pluralization included" do assert_equal Backend, I18n.backend.class end # links: test that keys stored on one backend can link to keys stored on another backend end i18n-0.7.0/test/api/chain_test.rb0000644000004100000410000000126112461054500016520 0ustar www-datawww-datarequire 'test_helper' class I18nApiChainTest < I18n::TestCase def setup super I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Simple.new, I18n.backend) end include I18n::Tests::Basics include I18n::Tests::Defaults include I18n::Tests::Interpolation include I18n::Tests::Link include I18n::Tests::Lookup include I18n::Tests::Pluralization include I18n::Tests::Procs include I18n::Tests::Localization::Date include I18n::Tests::Localization::DateTime include I18n::Tests::Localization::Time include I18n::Tests::Localization::Procs test "make sure we use the Chain backend" do assert_equal I18n::Backend::Chain, I18n.backend.class end end i18n-0.7.0/test/test_data/0000755000004100000410000000000012461054500015251 5ustar www-datawww-datai18n-0.7.0/test/test_data/locales/0000755000004100000410000000000012461054500016673 5ustar www-datawww-datai18n-0.7.0/test/test_data/locales/en.yml0000644000004100000410000000002712461054500020017 0ustar www-datawww-dataen: foo: bar: bazi18n-0.7.0/test/test_data/locales/plurals.rb0000644000004100000410000003477112461054500020716 0ustar www-datawww-data# encoding: utf-8 { :af => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :am => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } }, :ar => { :i18n => { :plural => { :keys => [:zero, :one, :two, :few, :many, :other], :rule => lambda { |n| n == 0 ? :zero : n == 1 ? :one : n == 2 ? :two : [3, 4, 5, 6, 7, 8, 9, 10].include?(n % 100) ? :few : [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].include?(n % 100) ? :many : :other } } } }, :az => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :be => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } }, :bg => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :bh => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } }, :bn => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :bo => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :bs => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } }, :ca => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :cs => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n == 1 ? :one : [2, 3, 4].include?(n) ? :few : :other } } } }, :cy => { :i18n => { :plural => { :keys => [:one, :two, :many, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : n == 8 || n == 11 ? :many : :other } } } }, :da => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :de => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :dz => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :el => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :en => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :eo => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :es => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :et => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :eu => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :fa => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :fi => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :fil => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } }, :fo => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :fr => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n.between?(0, 2) && n != 2 ? :one : :other } } } }, :fur => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :fy => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :ga => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } }, :gl => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :gu => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :guw => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } }, :ha => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :he => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :hi => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } }, :hr => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } }, :hu => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :id => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :is => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :it => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :iw => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :ja => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :jv => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :ka => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :km => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :kn => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :ko => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :ku => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :lb => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :ln => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } }, :lt => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n % 10 == 1 && ![11, 12, 13, 14, 15, 16, 17, 18, 19].include?(n % 100) ? :one : [2, 3, 4, 5, 6, 7, 8, 9].include?(n % 10) && ![11, 12, 13, 14, 15, 16, 17, 18, 19].include?(n % 100) ? :few : :other } } } }, :lv => { :i18n => { :plural => { :keys => [:zero, :one, :other], :rule => lambda { |n| n == 0 ? :zero : n % 10 == 1 && n % 100 != 11 ? :one : :other } } } }, :mg => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } }, :mk => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n % 10 == 1 ? :one : :other } } } }, :ml => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :mn => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :mo => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n == 1 ? :one : n == 0 ? :few : :other } } } }, :mr => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :ms => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :mt => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n == 1 ? :one : n == 0 || [2, 3, 4, 5, 6, 7, 8, 9, 10].include?(n % 100) ? :few : [11, 12, 13, 14, 15, 16, 17, 18, 19].include?(n % 100) ? :many : :other } } } }, :my => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :nah => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :nb => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :ne => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :nl => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :nn => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :no => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :nso => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } }, :om => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :or => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :pa => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :pap => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :pl => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n == 1 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : :other } } } }, :ps => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :pt => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } }, :"pt-PT" => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :ro => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n == 1 ? :one : n == 0 ? :few : :other } } } }, :ru => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } }, :se => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } }, :sh => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } }, :sk => { :i18n => { :plural => { :keys => [:one, :few, :other], :rule => lambda { |n| n == 1 ? :one : [2, 3, 4].include?(n) ? :few : :other } } } }, :sl => { :i18n => { :plural => { :keys => [:one, :two, :few, :other], :rule => lambda { |n| n % 100 == 1 ? :one : n % 100 == 2 ? :two : [3, 4].include?(n % 100) ? :few : :other } } } }, :sma => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } }, :smi => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } }, :smj => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } }, :smn => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } }, :sms => { :i18n => { :plural => { :keys => [:one, :two, :other], :rule => lambda { |n| n == 1 ? :one : n == 2 ? :two : :other } } } }, :so => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :sq => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :sr => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } }, :sv => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :sw => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :ta => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :te => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :th => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :ti => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } }, :tk => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :tl => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } }, :to => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :tr => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :uk => { :i18n => { :plural => { :keys => [:one, :few, :many, :other], :rule => lambda { |n| n % 10 == 1 && n % 100 != 11 ? :one : [2, 3, 4].include?(n % 10) && ![12, 13, 14].include?(n % 100) ? :few : n % 10 == 0 || [5, 6, 7, 8, 9].include?(n % 10) || [11, 12, 13, 14].include?(n % 100) ? :many : :other } } } }, :ur => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } }, :vi => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :wa => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| [0, 1].include?(n) ? :one : :other } } } }, :yo => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :zh => { :i18n => { :plural => { :keys => [:other], :rule => lambda { |n| :other } } } }, :zu => { :i18n => { :plural => { :keys => [:one, :other], :rule => lambda { |n| n == 1 ? :one : :other } } } } } i18n-0.7.0/test/test_data/locales/invalid/0000755000004100000410000000000012461054500020321 5ustar www-datawww-datai18n-0.7.0/test/test_data/locales/invalid/syntax.yml0000644000004100000410000000003512461054500022370 0ustar www-datawww-dataen: foo: foo bar: baz:i18n-0.7.0/test/test_data/locales/invalid/empty.yml0000644000004100000410000000000012461054500022170 0ustar www-datawww-datai18n-0.7.0/test/test_data/locales/de.po0000644000004100000410000000400412461054500017621 0ustar www-datawww-data# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: version 0.0.1\n" "POT-Creation-Date: 2009-02-26 19:50+0100\n" "PO-Revision-Date: 2009-02-18 14:53+0100\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" # #: app/helpers/translation_helper.rb:3 # msgid "%{relative_time} ago" # msgstr "vor %{relative_time}" #: app/views/cars/show.html.erb:5 msgid "Axis" msgid_plural "Axis" msgstr[0] "Achse" msgstr[1] "Achsen" #: app/controllers/cars_controller.rb:47 msgid "Car was successfully created." msgstr "Auto wurde erfolgreich gespeichert" #: app/controllers/cars_controller.rb:64 msgid "Car was successfully updated." msgstr "Auto wurde erfolgreich aktualisiert" #: app/views/cars/show.html.erb:1 locale/model_attributes.rb:3 msgid "Car|Model" msgstr "Modell" #: app/views/cars/show.html.erb:3 locale/model_attributes.rb:4 msgid "Car|Wheels count" msgstr "Räderzahl" msgctxt "New car" msgid "Wheels count" msgstr "Räderzahl!" #: app/views/cars/show.html.erb:7 msgid "Created" msgstr "Erstellt" #: app/views/cars/show.html.erb:9 msgid "Month" msgstr "Monat" #: locale/model_attributes.rb:2 msgid "car" msgstr "Auto" #: locale/testlog_phrases.rb:2 msgid "this is a dynamic translation which was found thorugh gettext_test_log!" msgstr "" "Dies ist eine dynamische Übersetzung, die durch gettext_test_log " "gefunden wurde!" #: app/views/cars/nowhere_really msgid "Car|wheel" msgid_plural "Car|wheels" msgstr[0] "Rad" msgstr[1] "Räder" msgctxt "New car" msgid "wheel" msgid_plural "wheels" msgstr[0] "Rad!" msgstr[1] "Räder!" msgid "On %{count} wheel." msgid_plural "On %{count} wheels." msgstr[0] "Auf %{count} Achse." msgstr[1] "Auf %{count} Achsen." i18n-0.7.0/test/test_data/locales/en.rb0000644000004100000410000000007312461054500017622 0ustar www-datawww-data# encoding: utf-8 { :en => { :fuh => { :bah => "bas" } } }i18n-0.7.0/test/gettext/0000755000004100000410000000000012461054500014765 5ustar www-datawww-datai18n-0.7.0/test/gettext/api_test.rb0000644000004100000410000002055712461054500017133 0ustar www-datawww-data# encoding: utf-8 require 'test_helper' require 'i18n/gettext/helpers' include I18n::Gettext::Helpers class I18nGettextApiTest < I18n::TestCase def setup super I18n.locale = :en I18n.backend.store_translations :de, { 'Hi Gettext!' => 'Hallo Gettext!', 'Sentence 1. Sentence 2.' => 'Satz 1. Satz 2.', "An apple" => { :one => 'Ein Apfel', :other => '%{count} Äpfel' }, :special => { "A special apple" => { :one => 'Ein spezieller Apfel', :other => '%{count} spezielle Äpfel' } }, :foo => { :bar => 'bar-de' }, 'foo.bar' => 'Foo Bar' }, :separator => '|' end # gettext def test_gettext_uses_msg_as_default assert_equal 'Hi Gettext!', _('Hi Gettext!') end def test_gettext_uses_msg_as_key I18n.locale = :de assert_equal 'Hallo Gettext!', gettext('Hi Gettext!') assert_equal 'Hallo Gettext!', _('Hi Gettext!') end def test_gettext_uses_msg_containing_dots_as_default assert_equal 'Sentence 1. Sentence 2.', gettext('Sentence 1. Sentence 2.') assert_equal 'Sentence 1. Sentence 2.', _('Sentence 1. Sentence 2.') end def test_gettext_uses_msg_containing_dots_as_key I18n.locale = :de assert_equal 'Satz 1. Satz 2.', gettext('Sentence 1. Sentence 2.') assert_equal 'Satz 1. Satz 2.', _('Sentence 1. Sentence 2.') end # sgettext def test_sgettext_defaults_to_the_last_token_of_a_scoped_msgid assert_equal 'bar', sgettext('foo|bar') assert_equal 'bar', s_('foo|bar') end def test_sgettext_looks_up_a_scoped_translation I18n.locale = :de assert_equal 'bar-de', sgettext('foo|bar') assert_equal 'bar-de', s_('foo|bar') end def test_sgettext_ignores_dots I18n.locale = :de assert_equal 'Foo Bar', sgettext('foo.bar') assert_equal 'Foo Bar', s_('foo.bar') end # pgettext def test_pgettext_defaults_to_msgid assert_equal 'bar', pgettext('foo', 'bar') assert_equal 'bar', p_('foo', 'bar') end def test_pgettext_looks_up_a_scoped_translation I18n.locale = :de assert_equal 'bar-de', pgettext('foo', 'bar') assert_equal 'bar-de', p_('foo', 'bar') end # ngettext def test_ngettext_looks_up_msg_id_as_default_singular assert_equal 'An apple', ngettext('An apple', '%{count} apples', 1) assert_equal 'An apple', n_('An apple', '%{count} apples', 1) end def test_ngettext_looks_up_msg_id_plural_as_default_plural assert_equal '2 apples', ngettext('An apple', '%{count} apples', 2) assert_equal '2 apples', n_('An apple', '%{count} apples', 2) end def test_ngettext_looks_up_a_singular I18n.locale = :de assert_equal 'Ein Apfel', ngettext('An apple', '%{count} apples', 1) assert_equal 'Ein Apfel', n_('An apple', '%{count} apples', 1) end def test_ngettext_looks_up_a_plural I18n.locale = :de assert_equal '2 Äpfel', ngettext('An apple', '%{count} apples', 2) assert_equal '2 Äpfel', n_('An apple', '%{count} apples', 2) end def test_ngettext_looks_up_msg_id_as_default_singular_with_alternative_syntax assert_equal 'An apple', ngettext(['An apple', '%{count} apples'], 1) assert_equal 'An apple', n_(['An apple', '%{count} apples'], 1) end def test_ngettext_looks_up_msg_id_plural_as_default_plural_with_alternative_syntax assert_equal '2 apples', ngettext(['An apple', '%{count} apples'], 2) assert_equal '2 apples', n_(['An apple', '%{count} apples'], 2) end def test_ngettext_looks_up_a_singular_with_alternative_syntax I18n.locale = :de assert_equal 'Ein Apfel', ngettext(['An apple', '%{count} apples'], 1) assert_equal 'Ein Apfel', n_(['An apple', '%{count} apples'], 1) end def test_ngettext_looks_up_a_plural_with_alternative_syntax I18n.locale = :de assert_equal '2 Äpfel', ngettext(['An apple', '%{count} apples'], 2) assert_equal '2 Äpfel', n_(['An apple', '%{count} apples'], 2) end # nsgettext def test_nsgettext_looks_up_msg_id_as_default_singular assert_equal 'A special apple', nsgettext('special|A special apple', '%{count} special apples', 1) assert_equal 'A special apple', ns_('special|A special apple', '%{count} special apples', 1) end def test_nsgettext_looks_up_msg_id_plural_as_default_plural assert_equal '2 special apples', nsgettext('special|A special apple', '%{count} special apples', 2) assert_equal '2 special apples', ns_('special|A special apple', '%{count} special apples', 2) end def test_nsgettext_looks_up_a_singular I18n.locale = :de assert_equal 'Ein spezieller Apfel', nsgettext('special|A special apple', '%{count} special apples', 1) assert_equal 'Ein spezieller Apfel', ns_('special|A special apple', '%{count} special apples', 1) end def test_nsgettext_looks_up_a_plural I18n.locale = :de assert_equal '2 spezielle Äpfel', nsgettext('special|A special apple', '%{count} special apples', 2) assert_equal '2 spezielle Äpfel', ns_('special|A special apple', '%{count} special apples', 2) end def test_nsgettext_looks_up_msg_id_as_default_singular_with_alternative_syntax assert_equal 'A special apple', nsgettext(['special|A special apple', '%{count} special apples'], 1) assert_equal 'A special apple', ns_(['special|A special apple', '%{count} special apples'], 1) end def test_nsgettext_looks_up_msg_id_plural_as_default_plural_with_alternative_syntax assert_equal '2 special apples', nsgettext(['special|A special apple', '%{count} special apples'], 2) assert_equal '2 special apples', ns_(['special|A special apple', '%{count} special apples'], 2) end def test_nsgettext_looks_up_a_singular_with_alternative_syntax I18n.locale = :de assert_equal 'Ein spezieller Apfel', nsgettext(['special|A special apple', '%{count} special apples'], 1) assert_equal 'Ein spezieller Apfel', ns_(['special|A special apple', '%{count} special apples'], 1) end def test_nsgettext_looks_up_a_plural_with_alternative_syntax I18n.locale = :de assert_equal '2 spezielle Äpfel', nsgettext(['special|A special apple', '%{count} special apples'], 2) assert_equal '2 spezielle Äpfel', ns_(['special|A special apple', '%{count} special apples'], 2) end # npgettext def test_npgettext_looks_up_msg_id_as_default_singular assert_equal 'A special apple', npgettext('special', 'A special apple', '%{count} special apples', 1) assert_equal 'A special apple', np_('special', 'A special apple', '%{count} special apples', 1) end def test_npgettext_looks_up_msg_id_plural_as_default_plural assert_equal '2 special apples', npgettext('special', 'A special apple', '%{count} special apples', 2) assert_equal '2 special apples', np_('special', 'A special apple', '%{count} special apples', 2) end def test_npgettext_looks_up_a_singular I18n.locale = :de assert_equal 'Ein spezieller Apfel', npgettext('special', 'A special apple', '%{count} special apples', 1) assert_equal 'Ein spezieller Apfel', np_('special', 'A special apple', '%{count} special apples', 1) end def test_npgettext_looks_up_a_plural I18n.locale = :de assert_equal '2 spezielle Äpfel', npgettext('special', 'A special apple', '%{count} special apples', 2) assert_equal '2 spezielle Äpfel', np_('special', 'A special apple', '%{count} special apples', 2) end def test_npgettext_looks_up_msg_id_as_default_singular_with_alternative_syntax assert_equal 'A special apple', npgettext('special', ['A special apple', '%{count} special apples'], 1) assert_equal 'A special apple', np_('special', ['A special apple', '%{count} special apples'], 1) end def test_npgettext_looks_up_msg_id_plural_as_default_plural_with_alternative_syntax assert_equal '2 special apples', npgettext('special', ['A special apple', '%{count} special apples'], 2) assert_equal '2 special apples', np_('special', ['A special apple', '%{count} special apples'], 2) end def test_npgettext_looks_up_a_singular_with_alternative_syntax I18n.locale = :de assert_equal 'Ein spezieller Apfel', npgettext('special', ['A special apple', '%{count} special apples'], 1) assert_equal 'Ein spezieller Apfel', np_('special', ['A special apple', '%{count} special apples'], 1) end def test_npgettext_looks_up_a_plural_with_alternative_syntax I18n.locale = :de assert_equal '2 spezielle Äpfel', npgettext('special', ['A special apple', '%{count} special apples'], 2) assert_equal '2 spezielle Äpfel', np_('special', ['A special apple', '%{count} special apples'], 2) end end i18n-0.7.0/test/gettext/backend_test.rb0000644000004100000410000000615412461054500017746 0ustar www-datawww-data# encoding: utf-8 require 'test_helper' class I18nGettextBackendTest < I18n::TestCase include I18n::Gettext::Helpers class Backend < I18n::Backend::Simple include I18n::Backend::Gettext end def setup super I18n.backend = Backend.new I18n.locale = :en I18n.load_path = ["#{locales_dir}/de.po"] I18n.default_separator = '|' end def test_backend_loads_po_file I18n.backend.send(:init_translations) assert I18n.backend.send(:translations)[:de][:"Axis"] end def test_looks_up_a_translation I18n.locale = :de assert_equal 'Auto', gettext('car') end def test_uses_default_translation assert_equal 'car', gettext('car') end def test_looks_up_a_namespaced_translation I18n.locale = :de assert_equal 'Räderzahl', sgettext('Car|Wheels count') assert_equal 'Räderzahl', pgettext('Car', 'Wheels count') assert_equal 'Räderzahl!', pgettext('New car', 'Wheels count') end def test_uses_namespaced_default_translation assert_equal 'Wheels count', sgettext('Car|Wheels count') assert_equal 'Wheels count', pgettext('Car', 'Wheels count') assert_equal 'Wheels count', pgettext('New car', 'Wheels count') end def test_pluralizes_entry I18n.locale = :de assert_equal 'Achse', ngettext('Axis', 'Axis', 1) assert_equal 'Achsen', ngettext('Axis', 'Axis', 2) end def test_pluralizes_default_entry assert_equal 'Axis', ngettext('Axis', 'Axis', 1) assert_equal 'Axis', ngettext('Axis', 'Axis', 2) end def test_pluralizes_namespaced_entry I18n.locale = :de assert_equal 'Rad', nsgettext('Car|wheel', 'wheels', 1) assert_equal 'Räder', nsgettext('Car|wheel', 'wheels', 2) assert_equal 'Rad', npgettext('Car', 'wheel', 'wheels', 1) assert_equal 'Räder', npgettext('Car', 'wheel', 'wheels', 2) assert_equal 'Rad!', npgettext('New car', 'wheel', 'wheels', 1) assert_equal 'Räder!', npgettext('New car', 'wheel', 'wheels', 2) end def test_pluralizes_namespaced_default_entry assert_equal 'wheel', nsgettext('Car|wheel', 'wheels', 1) assert_equal 'wheels', nsgettext('Car|wheel', 'wheels', 2) assert_equal 'wheel', npgettext('Car', 'wheel', 'wheels', 1) assert_equal 'wheels', npgettext('Car', 'wheel', 'wheels', 2) assert_equal 'wheel', npgettext('New car', 'wheel', 'wheels', 1) assert_equal 'wheels', npgettext('New car', 'wheel', 'wheels', 2) end def test_pluralizes_namespaced_entry_with_alternative_syntax I18n.locale = :de assert_equal 'Rad', nsgettext(['Car|wheel', 'wheels'], 1) assert_equal 'Räder', nsgettext(['Car|wheel', 'wheels'], 2) assert_equal 'Rad', npgettext('Car', ['wheel', 'wheels'], 1) assert_equal 'Räder', npgettext('Car', ['wheel', 'wheels'], 2) assert_equal 'Rad!', npgettext('New car', ['wheel', 'wheels'], 1) assert_equal 'Räder!', npgettext('New car', ['wheel', 'wheels'], 2) end def test_ngettextpluralizes_entry_with_dots I18n.locale = :de assert_equal 'Auf 1 Achse.', n_("On %{count} wheel.", "On %{count} wheels.", 1) assert_equal 'Auf 2 Achsen.', n_("On %{count} wheel.", "On %{count} wheels.", 2) end end i18n-0.7.0/test/test_helper.rb0000644000004100000410000000213412461054500016144 0ustar www-datawww-data$KCODE = 'u' if RUBY_VERSION <= '1.9' require 'minitest/autorun' TEST_CASE = defined?(Minitest::Test) ? Minitest::Test : MiniTest::Unit::TestCase # TODO: Remove these aliases and update tests accordingly. class TEST_CASE alias :assert_raise :assert_raises alias :assert_not_equal :refute_equal def assert_nothing_raised(*args) yield end end require 'bundler/setup' require 'i18n' require 'mocha/setup' require 'test_declarative' class I18n::TestCase < TEST_CASE def self.key_value? defined?(ActiveSupport) end def setup super I18n.enforce_available_locales = false end def teardown I18n.locale = nil I18n.default_locale = nil I18n.load_path = nil I18n.available_locales = nil I18n.backend = nil I18n.default_separator = nil I18n.enforce_available_locales = true super end protected def translations I18n.backend.instance_variable_get(:@translations) end def store_translations(locale, data) I18n.backend.store_translations(locale, data) end def locales_dir File.dirname(__FILE__) + '/test_data/locales' end end i18n-0.7.0/test/run_all.rb0000644000004100000410000000077612461054500015274 0ustar www-datawww-datadef bundle_check `bundle check` == "Resolving dependencies...\nThe Gemfile's dependencies are satisfied\n" end def execute(command) puts command system command end gemfiles = %w(Gemfile) + Dir['gemfiles/Gemfile*'].reject { |f| f.end_with?('.lock') } results = gemfiles.map do |gemfile| puts "\nBUNDLE_GEMFILE=#{gemfile}" ENV['BUNDLE_GEMFILE'] = File.expand_path("../../#{gemfile}", __FILE__) execute 'bundle install' unless bundle_check execute 'bundle exec rake test' end exit results.all? i18n-0.7.0/test/backend/0000755000004100000410000000000012461054500014670 5ustar www-datawww-datai18n-0.7.0/test/backend/simple_test.rb0000644000004100000410000000624512461054500017554 0ustar www-datawww-datarequire 'test_helper' class I18nBackendSimpleTest < I18n::TestCase def setup super I18n.backend = I18n::Backend::Simple.new I18n.load_path = [locales_dir + '/en.yml'] end # useful because this way we can use the backend with no key for interpolation/pluralization test "simple backend translate: given nil as a key it still interpolations the default value" do assert_equal "Hi David", I18n.t(nil, :default => "Hi %{name}", :name => "David") end # loading translations test "simple load_translations: given an unknown file type it raises I18n::UnknownFileType" do assert_raise(I18n::UnknownFileType) { I18n.backend.load_translations("#{locales_dir}/en.xml") } end test "simple load_translations: given a Ruby file name it does not raise anything" do assert_nothing_raised { I18n.backend.load_translations("#{locales_dir}/en.rb") } end test "simple load_translations: given no argument, it uses I18n.load_path" do I18n.backend.load_translations assert_equal({ :en => { :foo => { :bar => 'baz' } } }, I18n.backend.send(:translations)) end test "simple load_rb: loads data from a Ruby file" do data = I18n.backend.send(:load_rb, "#{locales_dir}/en.rb") assert_equal({ :en => { :fuh => { :bah => 'bas' } } }, data) end test "simple load_yml: loads data from a YAML file" do data = I18n.backend.send(:load_yml, "#{locales_dir}/en.yml") assert_equal({ 'en' => { 'foo' => { 'bar' => 'baz' } } }, data) end test "simple load_translations: loads data from known file formats" do I18n.backend = I18n::Backend::Simple.new I18n.backend.load_translations("#{locales_dir}/en.rb", "#{locales_dir}/en.yml") expected = { :en => { :fuh => { :bah => "bas" }, :foo => { :bar => "baz" } } } assert_equal expected, translations end test "simple load_translations: given file names as array it does not raise anything" do assert_nothing_raised { I18n.backend.load_translations(["#{locales_dir}/en.rb", "#{locales_dir}/en.yml"]) } end # storing translations test "simple store_translations: stores translations, ... no, really :-)" do store_translations :'en', :foo => 'bar' assert_equal Hash[:'en', {:foo => 'bar'}], translations end test "simple store_translations: deep_merges with existing translations" do store_translations :'en', :foo => {:bar => 'bar'} store_translations :'en', :foo => {:baz => 'baz'} assert_equal Hash[:'en', {:foo => {:bar => 'bar', :baz => 'baz'}}], translations end test "simple store_translations: converts the given locale to a Symbol" do store_translations 'en', :foo => 'bar' assert_equal Hash[:'en', {:foo => 'bar'}], translations end test "simple store_translations: converts keys to Symbols" do store_translations 'en', 'foo' => {'bar' => 'bar', 'baz' => 'baz'} assert_equal Hash[:'en', {:foo => {:bar => 'bar', :baz => 'baz'}}], translations end # reloading translations test "simple reload_translations: unloads translations" do I18n.backend.reload! assert_nil translations end test "simple reload_translations: uninitializes the backend" do I18n.backend.reload! assert_equal false, I18n.backend.initialized? end end i18n-0.7.0/test/backend/cache_test.rb0000644000004100000410000000503512461054500017322 0ustar www-datawww-datarequire 'test_helper' begin require 'active_support' rescue LoadError $stderr.puts "Skipping cache tests using ActiveSupport" else class I18nBackendCacheTest < I18n::TestCase class Backend < I18n::Backend::Simple include I18n::Backend::Cache end def setup I18n.backend = Backend.new super I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store) end def teardown super I18n.cache_store = nil end test "it uses the cache" do assert I18n.cache_store.is_a?(ActiveSupport::Cache::MemoryStore) end test "translate hits the backend and caches the response" do I18n.backend.expects(:lookup).returns('Foo') assert_equal 'Foo', I18n.t(:foo) I18n.backend.expects(:lookup).never assert_equal 'Foo', I18n.t(:foo) I18n.backend.expects(:lookup).returns('Bar') assert_equal 'Bar', I18n.t(:bar) end test "still raises MissingTranslationData but also caches it" do assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) } assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) } assert_equal 1, I18n.cache_store.instance_variable_get(:@data).size # I18n.backend.expects(:lookup).returns(nil) # assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) } # I18n.backend.expects(:lookup).never # assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) } end test "uses 'i18n' as a cache key namespace by default" do assert_equal 0, I18n.backend.send(:cache_key, :en, :foo, {}).index('i18n') end test "adds a custom cache key namespace" do with_cache_namespace('bar') do assert_equal 0, I18n.backend.send(:cache_key, :en, :foo, {}).index('i18n/bar/') end end test "adds locale and hash of key and hash of options" do options = { :bar=>1 } options_hash = I18n::Backend::Cache::USE_INSPECT_HASH ? options.inspect.hash : options.hash assert_equal "i18n//en/#{:foo.hash}/#{options_hash}", I18n.backend.send(:cache_key, :en, :foo, options) end test "keys should not be equal" do interpolation_values1 = { :foo => 1, :bar => 2 } interpolation_values2 = { :foo => 2, :bar => 1 } key1 = I18n.backend.send(:cache_key, :en, :some_key, interpolation_values1) key2 = I18n.backend.send(:cache_key, :en, :some_key, interpolation_values2) assert key1 != key2 end protected def with_cache_namespace(namespace) I18n.cache_namespace = namespace yield I18n.cache_namespace = nil end end end # AS cache check i18n-0.7.0/test/backend/key_value_test.rb0000644000004100000410000000305212461054500020240 0ustar www-datawww-datarequire 'test_helper' class I18nBackendKeyValueTest < I18n::TestCase def setup_backend!(subtree=true) I18n.backend = I18n::Backend::KeyValue.new({}, subtree) store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' }) end def assert_flattens(expected, nested, escape=true, subtree=true) assert_equal expected, I18n.backend.flatten_translations("en", nested, escape, subtree) end test "hash flattening works" do setup_backend! assert_flattens( {:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}, :"b.f" => {:x=>"x"}, :"b.c"=>"c", :"b.f.x"=>"x", :"b.d"=>"d"}, {:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}} ) assert_flattens({:a=>{:b =>['a', 'b']}, :"a.b"=>['a', 'b']}, {:a=>{:b =>['a', 'b']}}) assert_flattens({:"a\001b" => "c"}, {:"a.b" => "c"}) assert_flattens({:"a.b"=>['a', 'b']}, {:a=>{:b =>['a', 'b']}}, true, false) assert_flattens({:"a.b" => "c"}, {:"a.b" => "c"}, false) end test "store_translations handle subtrees by default" do setup_backend! assert_equal({ :bar => 'bar', :baz => 'baz' }, I18n.t("foo")) end test "store_translations merge subtrees accordingly" do setup_backend! store_translations(:en, :foo => { :baz => "BAZ"}) assert_equal('BAZ', I18n.t("foo.baz")) assert_equal({ :bar => 'bar', :baz => 'BAZ' }, I18n.t("foo")) end test "store_translations does not handle subtrees if desired" do setup_backend!(false) assert_raise I18n::MissingTranslationData do I18n.t("foo", :raise => true) end end end if I18n::TestCase.key_value? i18n-0.7.0/test/backend/transliterator_test.rb0000644000004100000410000000601412461054500021332 0ustar www-datawww-data# encoding: utf-8 require 'test_helper' class I18nBackendTransliterator < I18n::TestCase def setup super I18n.backend = I18n::Backend::Simple.new @proc = lambda { |n| n.upcase } @hash = { "ü" => "ue", "ö" => "oe", "a" => "a" } @transliterator = I18n::Backend::Transliterator.get end test "transliteration rule can be a proc" do store_translations(:xx, :i18n => {:transliterate => {:rule => @proc}}) assert_equal "HELLO", I18n.backend.transliterate(:xx, "hello") end test "transliteration rule can be a hash" do store_translations(:xx, :i18n => {:transliterate => {:rule => @hash}}) assert_equal "ue", I18n.backend.transliterate(:xx, "ü") end test "transliteration rule must be a proc or hash" do store_translations(:xx, :i18n => {:transliterate => {:rule => ""}}) assert_raise I18n::ArgumentError do I18n.backend.transliterate(:xx, "ü") end end test "transliterator defaults to latin => ascii when no rule is given" do assert_equal "AEroskobing", I18n.backend.transliterate(:xx, "Ærøskøbing") end test "default transliterator should not modify ascii characters" do (0..127).each do |byte| char = [byte].pack("U") assert_equal char, @transliterator.transliterate(char) end end test "default transliterator correctly transliterates latin characters" do # create string with range of Unicode's western characters with # diacritics, excluding the division and multiplication signs which for # some reason or other are floating in the middle of all the letters. string = (0xC0..0x17E).to_a.reject {|c| [0xD7, 0xF7].include? c}.pack("U*") string.split(//) do |char| assert_match %r{^[a-zA-Z']*$}, @transliterator.transliterate(string) end end test "should replace non-ASCII chars not in map with a replacement char" do assert_equal "abc?", @transliterator.transliterate("abcſ") end test "can replace non-ASCII chars not in map with a custom replacement string" do assert_equal "abc#", @transliterator.transliterate("abcſ", "#") end test "default transliterator raises errors for invalid UTF-8" do assert_raise ArgumentError do @transliterator.transliterate("a\x92b") end end test "I18n.transliterate should transliterate using a default transliterator" do assert_equal "aeo", I18n.transliterate("áèö") end test "I18n.transliterate should transliterate using a locale" do store_translations(:xx, :i18n => {:transliterate => {:rule => @hash}}) assert_equal "ue", I18n.transliterate("ü", :locale => :xx) end test "default transliterator fails with custom rules with uncomposed input" do char = [117, 776].pack("U*") # "ü" as ASCII "u" plus COMBINING DIAERESIS transliterator = I18n::Backend::Transliterator.get(@hash) assert_not_equal "ue", transliterator.transliterate(char) end test "DEFAULT_APPROXIMATIONS is frozen to prevent concurrency issues" do assert I18n::Backend::Transliterator::HashTransliterator::DEFAULT_APPROXIMATIONS.frozen? end end i18n-0.7.0/test/backend/cascade_test.rb0000644000004100000410000000704612461054500017646 0ustar www-datawww-datarequire 'test_helper' class I18nBackendCascadeTest < I18n::TestCase class Backend < I18n::Backend::Simple include I18n::Backend::Cascade end def setup super I18n.backend = Backend.new store_translations(:en, :foo => 'foo', :bar => { :baz => 'baz' }) @cascade_options = { :step => 1, :offset => 1, :skip_root => false } end def lookup(key, options = {}) I18n.t(key, options.merge(:cascade => @cascade_options)) end test "still returns an existing translation as usual" do assert_equal 'foo', lookup(:foo) assert_equal 'baz', lookup(:'bar.baz') end test "falls back by cutting keys off the end of the scope" do assert_equal 'foo', lookup(:foo, :scope => :'missing') assert_equal 'foo', lookup(:foo, :scope => :'missing.missing') assert_equal 'baz', lookup(:baz, :scope => :'bar.missing') assert_equal 'baz', lookup(:baz, :scope => :'bar.missing.missing') end test "raises I18n::MissingTranslationData exception when no translation was found" do assert_raise(I18n::MissingTranslationData) { lookup(:'foo.missing', :raise => true) } assert_raise(I18n::MissingTranslationData) { lookup(:'bar.baz.missing', :raise => true) } assert_raise(I18n::MissingTranslationData) { lookup(:'missing.bar.baz', :raise => true) } end test "cascades before evaluating the default" do assert_equal 'foo', lookup(:foo, :scope => :missing, :default => 'default') end test "cascades defaults, too" do assert_equal 'foo', lookup(nil, :default => [:'missing.missing', :'missing.foo']) end test "works with :offset => 2 and a single key" do @cascade_options[:offset] = 2 lookup(:foo) end test "assemble required fallbacks for ActiveRecord validation messages" do store_translations(:en, :errors => { :odd => 'errors.odd', :reply => { :title => { :blank => 'errors.reply.title.blank' }, :taken => 'errors.reply.taken' }, :topic => { :title => { :format => 'errors.topic.title.format' }, :length => 'errors.topic.length' } } ) assert_equal 'errors.reply.title.blank', lookup(:'errors.reply.title.blank', :default => :'errors.topic.title.blank') assert_equal 'errors.reply.taken', lookup(:'errors.reply.title.taken', :default => :'errors.topic.title.taken') assert_equal 'errors.topic.title.format', lookup(:'errors.reply.title.format', :default => :'errors.topic.title.format') assert_equal 'errors.topic.length', lookup(:'errors.reply.title.length', :default => :'errors.topic.title.length') assert_equal 'errors.odd', lookup(:'errors.reply.title.odd', :default => :'errors.topic.title.odd') end test "assemble action view translation helper lookup cascade" do @cascade_options[:offset] = 2 store_translations(:en, :menu => { :show => 'menu.show' }, :namespace => { :menu => { :new => 'namespace.menu.new' }, :controller => { :menu => { :edit => 'namespace.controller.menu.edit' }, :action => { :menu => { :destroy => 'namespace.controller.action.menu.destroy' } } } } ) assert_equal 'menu.show', lookup(:'namespace.controller.action.menu.show') assert_equal 'namespace.menu.new', lookup(:'namespace.controller.action.menu.new') assert_equal 'namespace.controller.menu.edit', lookup(:'namespace.controller.action.menu.edit') assert_equal 'namespace.controller.action.menu.destroy', lookup(:'namespace.controller.action.menu.destroy') end end i18n-0.7.0/test/backend/metadata_test.rb0000644000004100000410000000320212461054500020031 0ustar www-datawww-datarequire 'test_helper' class I18nBackendMetadataTest < I18n::TestCase class Backend < I18n::Backend::Simple include I18n::Backend::Metadata end def setup super I18n.backend = Backend.new store_translations(:en, :foo => 'Hi %{name}') end test "translation strings carry metadata" do translation = I18n.t(:foo, :name => 'David') assert translation.respond_to?(:translation_metadata) assert translation.translation_metadata.is_a?(Hash) end test "translate adds the locale to metadata on Strings" do assert_equal :en, I18n.t(:foo, :name => 'David', :locale => :en).translation_metadata[:locale] end test "translate adds the key to metadata on Strings" do assert_equal :foo, I18n.t(:foo, :name => 'David').translation_metadata[:key] end test "translate adds the default to metadata on Strings" do assert_equal 'bar', I18n.t(:foo, :default => 'bar', :name => '').translation_metadata[:default] end test "translation adds the interpolation values to metadata on Strings" do assert_equal({:name => 'David'}, I18n.t(:foo, :name => 'David').translation_metadata[:values]) end test "interpolation adds the original string to metadata on Strings" do assert_equal('Hi %{name}', I18n.t(:foo, :name => 'David').translation_metadata[:original]) end test "pluralization adds the count to metadata on Strings" do assert_equal(1, I18n.t(:missing, :count => 1, :default => { :one => 'foo' }).translation_metadata[:count]) end test "metadata works with frozen values" do assert_equal(1, I18n.t(:missing, :count => 1, :default => 'foo'.freeze).translation_metadata[:count]) end end i18n-0.7.0/test/backend/memoize_test.rb0000644000004100000410000000243212461054500017722 0ustar www-datawww-datarequire 'test_helper' # TODO: change back to "require 'backend/simple'" when dropping support to Ruby 1.8.7. require File.expand_path('../simple_test', __FILE__) class I18nBackendMemoizeTest < I18nBackendSimpleTest module MemoizeSpy attr_accessor :spy_calls def available_locales self.spy_calls = (self.spy_calls || 0) + 1 super end end class MemoizeBackend < I18n::Backend::Simple include MemoizeSpy include I18n::Backend::Memoize end def setup super I18n.backend = MemoizeBackend.new end def test_memoizes_available_locales I18n.backend.spy_calls = 0 assert_equal I18n.available_locales, I18n.available_locales assert_equal 1, I18n.backend.spy_calls end def test_resets_available_locales_on_reload! I18n.available_locales I18n.backend.spy_calls = 0 I18n.reload! assert_equal I18n.available_locales, I18n.available_locales assert_equal 1, I18n.backend.spy_calls end def test_resets_available_locales_on_store_translations I18n.available_locales I18n.backend.spy_calls = 0 I18n.backend.store_translations(:copa, :ca => :bana) assert_equal I18n.available_locales, I18n.available_locales assert I18n.available_locales.include?(:copa) assert_equal 1, I18n.backend.spy_calls end end i18n-0.7.0/test/backend/fallbacks_test.rb0000644000004100000410000001430712461054500020203 0ustar www-datawww-datarequire 'test_helper' class I18nBackendFallbacksTranslateTest < I18n::TestCase class Backend < I18n::Backend::Simple include I18n::Backend::Fallbacks end def setup super I18n.backend = Backend.new store_translations(:en, :foo => 'Foo in :en', :bar => 'Bar in :en', :buz => 'Buz in :en') store_translations(:de, :bar => 'Bar in :de', :baz => 'Baz in :de') store_translations(:'de-DE', :baz => 'Baz in :de-DE') store_translations(:'pt-BR', :baz => 'Baz in :pt-BR') end test "still returns an existing translation as usual" do assert_equal 'Foo in :en', I18n.t(:foo, :locale => :en) assert_equal 'Bar in :de', I18n.t(:bar, :locale => :de) assert_equal 'Baz in :de-DE', I18n.t(:baz, :locale => :'de-DE') end test "returns the :en translation for a missing :de translation" do assert_equal 'Foo in :en', I18n.t(:foo, :locale => :de) end test "returns the :de translation for a missing :'de-DE' translation" do assert_equal 'Bar in :de', I18n.t(:bar, :locale => :'de-DE') end test "returns the :en translation for translation missing in both :de and :'de-De'" do assert_equal 'Buz in :en', I18n.t(:buz, :locale => :'de-DE') end test "returns the :de translation for a missing :'de-DE' when :default is a String" do assert_equal 'Bar in :de', I18n.t(:bar, :locale => :'de-DE', :default => "Default Bar") assert_equal "Default Bar", I18n.t(:missing_bar, :locale => :'de-DE', :default => "Default Bar") end test "returns the :de translation for a missing :'de-DE' when defaults is a Symbol (which exists in :en)" do assert_equal "Bar in :de", I18n.t(:bar, :locale => :'de-DE', :default => [:buz]) end test "returns the :'de-DE' default :baz translation for a missing :'de-DE' (which exists in :de)" do assert_equal "Baz in :de-DE", I18n.t(:bar, :locale => :'de-DE', :default => [:baz]) end test "returns the :de translation for a missing :'de-DE' when :default is a Proc" do assert_equal 'Bar in :de', I18n.t(:bar, :locale => :'de-DE', :default => Proc.new { "Default Bar" }) assert_equal "Default Bar", I18n.t(:missing_bar, :locale => :'de-DE', :default => Proc.new { "Default Bar" }) end test "returns the :de translation for a missing :'de-DE' when :default is a Hash" do assert_equal 'Bar in :de', I18n.t(:bar, :locale => :'de-DE', :default => {}) assert_equal({}, I18n.t(:missing_bar, :locale => :'de-DE', :default => {})) end test "returns the :'de-DE' default :baz translation for a missing :'de-DE' when defaults contains Symbol" do assert_equal 'Baz in :de-DE', I18n.t(:missing_foo, :locale => :'de-DE', :default => [:baz, "Default Bar"]) end test "returns the defaults translation for a missing :'de-DE' when defaults contains a String or Proc before Symbol" do assert_equal "Default Bar", I18n.t(:missing_foo, :locale => :'de-DE', :default => [:missing_bar, "Default Bar", :baz]) assert_equal "Default Bar", I18n.t(:missing_foo, :locale => :'de-DE', :default => [:missing_bar, Proc.new { "Default Bar" }, :baz]) end test "returns the default translation for a missing :'de-DE' and existing :de when default is a Hash" do assert_equal 'Default 6 Bars', I18n.t(:missing_foo, :locale => :'de-DE', :default => [:missing_bar, {:other => "Default %{count} Bars"}, "Default Bar"], :count => 6) end test "raises I18n::MissingTranslationData exception when no translation was found" do assert_raise(I18n::MissingTranslationData) { I18n.t(:faa, :locale => :en, :raise => true) } assert_raise(I18n::MissingTranslationData) { I18n.t(:faa, :locale => :de, :raise => true) } end test "should ensure that default is not splitted on new line char" do assert_equal "Default \n Bar", I18n.t(:missing_bar, :default => "Default \n Bar") end test "should not raise error when enforce_available_locales is true, :'pt' is missing and default is a Symbol" do I18n.enforce_available_locales = true begin assert_equal 'Foo', I18n.t(:'model.attrs.foo', :locale => :'pt-BR', :default => [:'attrs.foo', "Foo"]) ensure I18n.enforce_available_locales = false end end end class I18nBackendFallbacksLocalizeTest < I18n::TestCase class Backend < I18n::Backend::Simple include I18n::Backend::Fallbacks end def setup super I18n.backend = Backend.new store_translations(:en, :date => { :formats => { :en => 'en' }, :day_names => %w(Sunday) }) store_translations(:de, :date => { :formats => { :de => 'de' } }) end test "still uses an existing format as usual" do assert_equal 'en', I18n.l(Date.today, :format => :en, :locale => :en) end test "looks up and uses a fallback locale's format for a key missing in the given locale (1)" do assert_equal 'en', I18n.l(Date.today, :format => :en, :locale => :de) end test "looks up and uses a fallback locale's format for a key missing in the given locale (2)" do assert_equal 'de', I18n.l(Date.today, :format => :de, :locale => :'de-DE') end test "still uses an existing day name translation as usual" do assert_equal 'Sunday', I18n.l(Date.new(2010, 1, 3), :format => '%A', :locale => :en) end test "uses a fallback locale's translation for a key missing in the given locale" do assert_equal 'Sunday', I18n.l(Date.new(2010, 1, 3), :format => '%A', :locale => :de) end end class I18nBackendFallbacksWithChainTest < I18n::TestCase class Backend < I18n::Backend::Simple include I18n::Backend::Fallbacks end class Chain < I18n::Backend::Chain include I18n::Backend::Fallbacks end def setup super backend = Backend.new backend.store_translations(:de, :foo => 'FOO') backend.store_translations(:'pt-BR', :foo => 'Baz in :pt-BR') I18n.backend = Chain.new(I18n::Backend::Simple.new, backend) end test "falls back from de-DE to de when there is no translation for de-DE available" do assert_equal 'FOO', I18n.t(:foo, :locale => :'de-DE') end test "should not raise error when enforce_available_locales is true, :'pt' is missing and default is a Symbol" do I18n.enforce_available_locales = true begin assert_equal 'Foo', I18n.t(:'model.attrs.foo', :locale => :'pt-BR', :default => [:'attrs.foo', "Foo"]) ensure I18n.enforce_available_locales = false end end end i18n-0.7.0/test/backend/pluralization_test.rb0000644000004100000410000000307312461054500021154 0ustar www-datawww-datarequire 'test_helper' class I18nBackendPluralizationTest < I18n::TestCase class Backend < I18n::Backend::Simple include I18n::Backend::Pluralization include I18n::Backend::Fallbacks end def setup super I18n.backend = Backend.new @rule = lambda { |n| n == 1 ? :one : n == 0 || (2..10).include?(n % 100) ? :few : (11..19).include?(n % 100) ? :many : :other } store_translations(:xx, :i18n => { :plural => { :rule => @rule } }) @entry = { :zero => 'zero', :one => 'one', :few => 'few', :many => 'many', :other => 'other' } end test "pluralization picks a pluralizer from :'i18n.pluralize'" do assert_equal @rule, I18n.backend.send(:pluralizer, :xx) end test "pluralization picks :one for 1" do assert_equal 'one', I18n.t(:count => 1, :default => @entry, :locale => :xx) end test "pluralization picks :few for 2" do assert_equal 'few', I18n.t(:count => 2, :default => @entry, :locale => :xx) end test "pluralization picks :many for 11" do assert_equal 'many', I18n.t(:count => 11, :default => @entry, :locale => :xx) end test "pluralization picks zero for 0 if the key is contained in the data" do assert_equal 'zero', I18n.t(:count => 0, :default => @entry, :locale => :xx) end test "pluralization picks few for 0 if the key is not contained in the data" do @entry.delete(:zero) assert_equal 'few', I18n.t(:count => 0, :default => @entry, :locale => :xx) end test "Fallbacks can pick up rules from fallback locales, too" do assert_equal @rule, I18n.backend.send(:pluralizer, :'xx-XX') end end i18n-0.7.0/test/backend/exceptions_test.rb0000644000004100000410000000262712461054500020444 0ustar www-datawww-datarequire 'test_helper' class I18nBackendExceptionsTest < I18n::TestCase def setup super I18n.backend = I18n::Backend::Simple.new end test "throw message: MissingTranslation message from #translate includes the given scope and full key" do exception = catch(:exception) do I18n.t(:'baz.missing', :scope => :'foo.bar', :throw => true) end assert_equal "translation missing: en.foo.bar.baz.missing", exception.message end test "exceptions: MissingTranslationData message from #translate includes the given scope and full key" do begin I18n.t(:'baz.missing', :scope => :'foo.bar', :raise => true) rescue I18n::MissingTranslationData => exception end assert_equal "translation missing: en.foo.bar.baz.missing", exception.message end test "exceptions: MissingTranslationData message from #localize includes the given scope and full key" do begin I18n.l(Time.now, :format => :foo) rescue I18n::MissingTranslationData => exception end assert_equal "translation missing: en.time.formats.foo", exception.message end test "exceptions: MissingInterpolationArgument message includes missing key, provided keys and full string" do exception = I18n::MissingInterpolationArgument.new('key', {:this => 'was given'}, 'string') assert_equal 'missing interpolation argument "key" in "string" ({:this=>"was given"} given)', exception.message end end i18n-0.7.0/test/backend/interpolation_compiler_test.rb0000644000004100000410000001076712461054500023050 0ustar www-datawww-datarequire 'test_helper' class InterpolationCompilerTest < I18n::TestCase Compiler = I18n::Backend::InterpolationCompiler::Compiler def compile_and_interpolate(str, values = {}) Compiler.compile_if_an_interpolation(str).i18n_interpolate(values) end def assert_escapes_interpolation_key(expected, malicious_str) assert_equal(expected, Compiler.send(:escape_key_sym, malicious_str)) end def test_escape_key_properly_escapes assert_escapes_interpolation_key ':"\""', '"' assert_escapes_interpolation_key ':"\\\\"', '\\' assert_escapes_interpolation_key ':"\\\\\""', '\\"' assert_escapes_interpolation_key ':"\#{}"', '#{}' assert_escapes_interpolation_key ':"\\\\\#{}"', '\#{}' end def assert_escapes_plain_string(expected, plain_str) assert_equal expected, Compiler.send(:escape_plain_str, plain_str) end def test_escape_plain_string_properly_escapes assert_escapes_plain_string '\\"', '"' assert_escapes_plain_string '\'', '\'' assert_escapes_plain_string '\\#', '#' assert_escapes_plain_string '\\#{}', '#{}' assert_escapes_plain_string '\\\\\\"','\\"' end def test_non_interpolated_strings_or_arrays_dont_get_compiled ['abc', '\\{a}}', '{a}}', []].each do |obj| Compiler.compile_if_an_interpolation(obj) assert_equal false, obj.respond_to?(:i18n_interpolate) end end def test_interpolated_string_gets_compiled assert_equal '-A-', compile_and_interpolate('-%{a}-', :a => 'A') end def assert_handles_key(str, key) assert_equal 'A', compile_and_interpolate(str, key => 'A') end def test_compiles_fancy_keys assert_handles_key('%{\}', :'\\' ) assert_handles_key('%{#}', :'#' ) assert_handles_key('%{#{}', :'#{' ) assert_handles_key('%{#$SAFE}', :'#$SAFE') assert_handles_key('%{\000}', :'\000' ) assert_handles_key('%{\'}', :'\'' ) assert_handles_key('%{\'\'}', :'\'\'' ) assert_handles_key('%{a.b}', :'a.b' ) assert_handles_key('%{ }', :' ' ) assert_handles_key('%{:}', :':' ) assert_handles_key("%{:''}", :":''" ) assert_handles_key('%{:"}', :':"' ) end def test_str_containing_only_escaped_interpolation_is_handled_correctly assert_equal 'abc %{x}', compile_and_interpolate('abc %%{x}') end def test_handles_weird_strings assert_equal '#{} a', compile_and_interpolate('#{} %{a}', :a => 'a') assert_equal '"#{abc}"', compile_and_interpolate('"#{ab%{a}c}"', :a => '' ) assert_equal 'a}', compile_and_interpolate('%{{a}}', :'{a' => 'a') assert_equal '"', compile_and_interpolate('"%{a}', :a => '' ) assert_equal 'a%{a}', compile_and_interpolate('%{a}%%{a}', :a => 'a') assert_equal '%%{a}', compile_and_interpolate('%%%{a}') assert_equal '\";eval("a")', compile_and_interpolate('\";eval("%{a}")', :a => 'a') assert_equal '\";eval("a")', compile_and_interpolate('\";eval("a")%{a}', :a => '' ) assert_equal "\na", compile_and_interpolate("\n%{a}", :a => 'a') end def test_raises_exception_when_argument_is_missing assert_raise(I18n::MissingInterpolationArgument) do compile_and_interpolate('%{first} %{last}', :first => 'first') end end def test_custom_missing_interpolation_argument_handler old_handler = I18n.config.missing_interpolation_argument_handler I18n.config.missing_interpolation_argument_handler = lambda do |key, values, string| "missing key is #{key}, values are #{values.inspect}, given string is '#{string}'" end assert_equal %|first missing key is last, values are {:first=>"first"}, given string is '%{first} %{last}'|, compile_and_interpolate('%{first} %{last}', :first => 'first') ensure I18n.config.missing_interpolation_argument_handler = old_handler end end class I18nBackendInterpolationCompilerTest < I18n::TestCase class Backend < I18n::Backend::Simple include I18n::Backend::InterpolationCompiler end include I18n::Tests::Interpolation def setup I18n.backend = Backend.new super end # pre-compile default strings to make sure we are testing I18n::Backend::InterpolationCompiler def interpolate(*args) options = args.last.kind_of?(Hash) ? args.last : {} if default_str = options[:default] I18n::Backend::InterpolationCompiler::Compiler.compile_if_an_interpolation(default_str) end super end end i18n-0.7.0/test/backend/chain_test.rb0000644000004100000410000000623312461054500017342 0ustar www-datawww-datarequire 'test_helper' class I18nBackendChainTest < I18n::TestCase def setup super @first = backend(:en => { :foo => 'Foo', :formats => { :short => 'short', :subformats => {:short => 'short'}, }, :plural_1 => { :one => '%{count}' }, :dates => {:a => "A"} }) @second = backend(:en => { :bar => 'Bar', :formats => { :long => 'long', :subformats => {:long => 'long'}, }, :plural_2 => { :one => 'one' }, :dates => {:a => "B", :b => "B"} }) @chain = I18n.backend = I18n::Backend::Chain.new(@first, @second) end test "looks up translations from the first chained backend" do assert_equal 'Foo', @first.send(:translations)[:en][:foo] assert_equal 'Foo', I18n.t(:foo) end test "looks up translations from the second chained backend" do assert_equal 'Bar', @second.send(:translations)[:en][:bar] assert_equal 'Bar', I18n.t(:bar) end test "defaults only apply to lookups on the last backend in the chain" do assert_equal 'Foo', I18n.t(:foo, :default => 'Bah') assert_equal 'Bar', I18n.t(:bar, :default => 'Bah') assert_equal 'Bah', I18n.t(:bah, :default => 'Bah') # default kicks in only here end test "default" do assert_equal 'Fuh', I18n.t(:default => 'Fuh') assert_equal 'Zero', I18n.t(:default => { :zero => 'Zero' }, :count => 0) assert_equal({ :zero => 'Zero' }, I18n.t(:default => { :zero => 'Zero' })) assert_equal 'Foo', I18n.t(:default => :foo) end test 'default is returned if translation is missing' do assert_equal({}, I18n.t(:'i18n.transliterate.rule', :locale => 'en', :default => {})) end test "namespace lookup collects results from all backends and merges deep hashes" do assert_equal({:long=>"long", :subformats=>{:long=>"long", :short=>"short"}, :short=>"short"}, I18n.t(:formats)) end test "namespace lookup collects results from all backends and lets leftmost backend take priority" do assert_equal({ :a => "A", :b => "B" }, I18n.t(:dates)) end test "namespace lookup with only the first backend returning a result" do assert_equal({ :one => '%{count}' }, I18n.t(:plural_1)) end test "pluralization still works" do assert_equal '1', I18n.t(:plural_1, :count => 1) assert_equal 'one', I18n.t(:plural_2, :count => 1) end test "bulk lookup collects results from all backends" do assert_equal ['Foo', 'Bar'], I18n.t([:foo, :bar]) assert_equal ['Foo', 'Bar', 'Bah'], I18n.t([:foo, :bar, :bah], :default => 'Bah') assert_equal [{ :long=>"long", :subformats=>{:long=>"long", :short=>"short"}, :short=>"short"}, {:one=>"one"}, "Bah"], I18n.t([:formats, :plural_2, :bah], :default => 'Bah') end test "store_translations options are not dropped while transfering to backend" do @first.expects(:store_translations).with(:foo, {:bar => :baz}, {:option => 'persists'}) I18n.backend.store_translations :foo, {:bar => :baz}, {:option => 'persists'} end protected def backend(translations) backend = I18n::Backend::Simple.new translations.each { |locale, data| backend.store_translations(locale, data) } backend end end i18n-0.7.0/test/locale/0000755000004100000410000000000012461054500014540 5ustar www-datawww-datai18n-0.7.0/test/locale/fallbacks_test.rb0000644000004100000410000001175512461054500020057 0ustar www-datawww-datarequire 'test_helper' include I18n::Locale class I18nFallbacksDefaultsTest < I18n::TestCase test "defaults reflect the I18n.default_locale if no default has been set manually" do I18n.default_locale = :'en-US' fallbacks = Fallbacks.new assert_equal [:'en-US', :en], fallbacks.defaults end test "defaults reflect a manually passed default locale if any" do fallbacks = Fallbacks.new(:'fi-FI') assert_equal [:'fi-FI', :fi], fallbacks.defaults I18n.default_locale = :'de-DE' assert_equal [:'fi-FI', :fi], fallbacks.defaults end test "defaults allows to set multiple defaults" do fallbacks = Fallbacks.new(:'fi-FI', :'se-FI') assert_equal [:'fi-FI', :fi, :'se-FI', :se], fallbacks.defaults end end class I18nFallbacksComputationTest < I18n::TestCase def setup super @fallbacks = Fallbacks.new(:'en-US') end test "with no mappings defined it returns [:es, :en-US] for :es" do assert_equal [:es, :"en-US", :en], @fallbacks[:es] end test "with no mappings defined it returns [:es-ES, :es, :en-US] for :es-ES" do assert_equal [:"es-ES", :es, :"en-US", :en], @fallbacks[:"es-ES"] end test "with no mappings defined it returns [:es-MX, :es, :en-US] for :es-MX" do assert_equal [:"es-MX", :es, :"en-US", :en], @fallbacks[:"es-MX"] end test "with no mappings defined it returns [:es-Latn-ES, :es-Latn, :es, :en-US] for :es-Latn-ES" do assert_equal [:"es-Latn-ES", :"es-Latn", :es, :"en-US", :en], @fallbacks[:'es-Latn-ES'] end test "with no mappings defined it returns [:en, :en-US] for :en" do assert_equal [:en, :"en-US"], @fallbacks[:en] end test "with no mappings defined it returns [:en-US, :en] for :en-US (special case: locale == default)" do assert_equal [:"en-US", :en], @fallbacks[:"en-US"] end # Most people who speak Catalan also live in Spain, so it is safe to assume # that they also speak Spanish as spoken in Spain. test "with a Catalan mapping defined it returns [:ca, :es-ES, :es, :en-US] for :ca" do @fallbacks.map(:ca => :"es-ES") assert_equal [:ca, :"es-ES", :es, :"en-US", :en], @fallbacks[:ca] end test "with a Catalan mapping defined it returns [:ca-ES, :ca, :es-ES, :es, :en-US] for :ca-ES" do @fallbacks.map(:ca => :"es-ES") assert_equal [:"ca-ES", :ca, :"es-ES", :es, :"en-US", :en], @fallbacks[:"ca-ES"] end # People who speak Arabic as spoken in Palestine often times also speak # Hebrew as spoken in Israel. However it is in no way safe to assume that # everybody who speaks Arabic also speaks Hebrew. test "with a Hebrew mapping defined it returns [:ar, :en-US] for :ar" do @fallbacks.map(:"ar-PS" => :"he-IL") assert_equal [:ar, :"en-US", :en], @fallbacks[:ar] end test "with a Hebrew mapping defined it returns [:ar-EG, :ar, :en-US] for :ar-EG" do @fallbacks.map(:"ar-PS" => :"he-IL") assert_equal [:"ar-EG", :ar, :"en-US", :en], @fallbacks[:"ar-EG"] end test "with a Hebrew mapping defined it returns [:ar-PS, :ar, :he-IL, :he, :en-US] for :ar-PS" do @fallbacks.map(:"ar-PS" => :"he-IL") assert_equal [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en], @fallbacks[:"ar-PS"] end # Sami people live in several scandinavian countries. In Finnland many people # know Swedish and Finnish. Thus, it can be assumed that Sami living in # Finnland also speak Swedish and Finnish. test "with a Sami mapping defined it returns [:sms-FI, :sms, :se-FI, :se, :fi-FI, :fi, :en-US] for :sms-FI" do @fallbacks.map(:sms => [:"se-FI", :"fi-FI"]) assert_equal [:"sms-FI", :sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en], @fallbacks[:"sms-FI"] end # Austrian people understand German as spoken in Germany test "with a German mapping defined it returns [:de, :en-US] for de" do @fallbacks.map(:"de-AT" => :"de-DE") assert_equal [:de, :"en-US", :en], @fallbacks[:"de"] end test "with a German mapping defined it returns [:de-DE, :de, :en-US] for de-DE" do @fallbacks.map(:"de-AT" => :"de-DE") assert_equal [:"de-DE", :de, :"en-US", :en], @fallbacks[:"de-DE"] end test "with a German mapping defined it returns [:de-AT, :de, :de-DE, :en-US] for de-AT" do @fallbacks.map(:"de-AT" => :"de-DE") assert_equal [:"de-AT", :de, :"de-DE", :"en-US", :en], @fallbacks[:"de-AT"] end # Mapping :de => :en, :he => :en test "with a mapping :de => :en, :he => :en defined it returns [:de, :en] for :de" do assert_equal [:de, :"en-US", :en], @fallbacks[:de] end test "with a mapping :de => :en, :he => :en defined it [:he, :en] for :de" do assert_equal [:he, :"en-US", :en], @fallbacks[:he] end # Test allowing mappings that fallback to each other test "with :no => :nb, :nb => :no defined :no returns [:no, :nb, :en-US, :en]" do @fallbacks.map(:no => :nb, :nb => :no) assert_equal [:no, :nb, :"en-US", :en], @fallbacks[:no] end test "with :no => :nb, :nb => :no defined :nb returns [:nb, :no, :en-US, :en]" do @fallbacks.map(:no => :nb, :nb => :no) assert_equal [:nb, :no, :"en-US", :en], @fallbacks[:nb] end end i18n-0.7.0/test/locale/tag/0000755000004100000410000000000012461054500015313 5ustar www-datawww-datai18n-0.7.0/test/locale/tag/simple_test.rb0000644000004100000410000000177212461054500020177 0ustar www-datawww-data# encoding: utf-8 require 'test_helper' class I18nLocaleTagSimpleTest < I18n::TestCase include I18n::Locale test "returns 'de' as the language subtag in lowercase" do assert_equal %w(de Latn DE), Tag::Simple.new('de-Latn-DE').subtags end test "returns a formatted tag string from #to_s" do assert_equal 'de-Latn-DE', Tag::Simple.new('de-Latn-DE').to_s end test "returns an array containing the formatted subtags from #to_a" do assert_equal %w(de Latn DE), Tag::Simple.new('de-Latn-DE').to_a end # Tag inheritance test "#parent returns 'de-Latn' as the parent of 'de-Latn-DE'" do assert_equal 'de-Latn', Tag::Simple.new('de-Latn-DE').parent.to_s end test "#parent returns 'de' as the parent of 'de-Latn'" do assert_equal 'de', Tag::Simple.new('de-Latn').parent.to_s end test "#self_and_parents returns an array of 3 tags for 'de-Latn-DE'" do assert_equal %w(de-Latn-DE de-Latn de), Tag::Simple.new('de-Latn-DE').self_and_parents.map { |tag| tag.to_s} end end i18n-0.7.0/test/locale/tag/rfc4646_test.rb0000644000004100000410000001211612461054500017776 0ustar www-datawww-data# encoding: utf-8 require 'test_helper' class I18nLocaleTagRfc4646ParserTest < I18n::TestCase include I18n::Locale test "Rfc4646::Parser given a valid tag 'de' returns an array of subtags" do assert_equal ['de', nil, nil, nil, nil, nil, nil], Tag::Rfc4646::Parser.match('de') end test "Rfc4646::Parser given a valid tag 'de-DE' returns an array of subtags" do assert_equal ['de', nil, 'DE', nil, nil, nil, nil], Tag::Rfc4646::Parser.match('de-DE') end test "Rfc4646::Parser given a valid lowercase tag 'de-latn-de-variant-x-phonebk' returns an array of subtags" do assert_equal ['de', 'latn', 'de', 'variant', nil, 'x-phonebk', nil], Tag::Rfc4646::Parser.match('de-latn-de-variant-x-phonebk') end test "Rfc4646::Parser given a valid uppercase tag 'DE-LATN-DE-VARIANT-X-PHONEBK' returns an array of subtags" do assert_equal ['DE', 'LATN', 'DE', 'VARIANT', nil, 'X-PHONEBK', nil], Tag::Rfc4646::Parser.match('DE-LATN-DE-VARIANT-X-PHONEBK') end test "Rfc4646::Parser given an invalid tag 'a-DE' it returns false" do assert_equal false, Tag::Rfc4646::Parser.match('a-DE') end test "Rfc4646::Parser given an invalid tag 'de-419-DE' it returns false" do assert_equal false, Tag::Rfc4646::Parser.match('de-419-DE') end end # Tag for the locale 'de-Latn-DE-Variant-a-ext-x-phonebk-i-klingon' class I18nLocaleTagSubtagsTest < I18n::TestCase include I18n::Locale def setup super subtags = %w(de Latn DE variant a-ext x-phonebk i-klingon) @tag = Tag::Rfc4646.new(*subtags) end test "returns 'de' as the language subtag in lowercase" do assert_equal 'de', @tag.language end test "returns 'Latn' as the script subtag in titlecase" do assert_equal 'Latn', @tag.script end test "returns 'DE' as the region subtag in uppercase" do assert_equal 'DE', @tag.region end test "returns 'variant' as the variant subtag in lowercase" do assert_equal 'variant', @tag.variant end test "returns 'a-ext' as the extension subtag" do assert_equal 'a-ext', @tag.extension end test "returns 'x-phonebk' as the privateuse subtag" do assert_equal 'x-phonebk', @tag.privateuse end test "returns 'i-klingon' as the grandfathered subtag" do assert_equal 'i-klingon', @tag.grandfathered end test "returns a formatted tag string from #to_s" do assert_equal 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon', @tag.to_s end test "returns an array containing the formatted subtags from #to_a" do assert_equal %w(de Latn DE variant a-ext x-phonebk i-klingon), @tag.to_a end end # Tag inheritance class I18nLocaleTagSubtagsTest < I18n::TestCase test "#parent returns 'de-Latn-DE-variant-a-ext-x-phonebk' as the parent of 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon'" do tag = Tag::Rfc4646.new(*%w(de Latn DE variant a-ext x-phonebk i-klingon)) assert_equal 'de-Latn-DE-variant-a-ext-x-phonebk', tag.parent.to_s end test "#parent returns 'de-Latn-DE-variant-a-ext' as the parent of 'de-Latn-DE-variant-a-ext-x-phonebk'" do tag = Tag::Rfc4646.new(*%w(de Latn DE variant a-ext x-phonebk)) assert_equal 'de-Latn-DE-variant-a-ext', tag.parent.to_s end test "#parent returns 'de-Latn-DE-variant' as the parent of 'de-Latn-DE-variant-a-ext'" do tag = Tag::Rfc4646.new(*%w(de Latn DE variant a-ext)) assert_equal 'de-Latn-DE-variant', tag.parent.to_s end test "#parent returns 'de-Latn-DE' as the parent of 'de-Latn-DE-variant'" do tag = Tag::Rfc4646.new(*%w(de Latn DE variant)) assert_equal 'de-Latn-DE', tag.parent.to_s end test "#parent returns 'de-Latn' as the parent of 'de-Latn-DE'" do tag = Tag::Rfc4646.new(*%w(de Latn DE)) assert_equal 'de-Latn', tag.parent.to_s end test "#parent returns 'de' as the parent of 'de-Latn'" do tag = Tag::Rfc4646.new(*%w(de Latn)) assert_equal 'de', tag.parent.to_s end # TODO RFC4647 says: "If no language tag matches the request, the "default" value is returned." # where should we set the default language? # test "#parent returns '' as the parent of 'de'" do # tag = Tag::Rfc4646.new *%w(de) # assert_equal '', tag.parent.to_s # end test "#parent returns an array of 5 parents for 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon'" do parents = %w(de-Latn-DE-variant-a-ext-x-phonebk-i-klingon de-Latn-DE-variant-a-ext-x-phonebk de-Latn-DE-variant-a-ext de-Latn-DE-variant de-Latn-DE de-Latn de) tag = Tag::Rfc4646.new(*%w(de Latn DE variant a-ext x-phonebk i-klingon)) assert_equal parents, tag.self_and_parents.map(&:to_s) end test "returns an array of 5 parents for 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon'" do parents = %w(de-Latn-DE-variant-a-ext-x-phonebk-i-klingon de-Latn-DE-variant-a-ext-x-phonebk de-Latn-DE-variant-a-ext de-Latn-DE-variant de-Latn-DE de-Latn de) tag = Tag::Rfc4646.new(*%w(de Latn DE variant a-ext x-phonebk i-klingon)) assert_equal parents, tag.self_and_parents.map(&:to_s) end end i18n-0.7.0/README.md0000644000004100000410000000462412461054500013607 0ustar www-datawww-data# Ruby I18n [![Build Status](https://api.travis-ci.org/svenfuchs/i18n.svg?branch=master)](https://travis-ci.org/svenfuchs/i18n) Ruby Internationalization and localization solution. Features: * translation and localization * interpolation of values to translations (Ruby 1.9 compatible syntax) * pluralization (CLDR compatible) * customizable transliteration to ASCII * flexible defaults * bulk lookup * lambdas as translation data * custom key/scope separator * custom exception handlers * extensible architecture with a swappable backend Pluggable features: * Cache * Pluralization: lambda pluralizers stored as translation data * Locale fallbacks, RFC4647 compliant (optionally: RFC4646 locale validation) * Gettext support * Translation metadata Alternative backends: * Chain * ActiveRecord (optionally: ActiveRecord::Missing and ActiveRecord::StoreProcs) * KeyValue (uses active_support/json and cannot store procs) For more information and lots of resources see: [http://ruby-i18n.org/wiki](http://ruby-i18n.org/wiki) ## Installation ``` gem install i18n ``` ## Tests You can run tests both with * `rake test` or just `rake` * run any test file directly, e.g. `ruby -Ilib:test test/api/simple_test.rb` You can run all tests against all Gemfiles with * `ruby test/run_all.rb` The structure of the test suite is a bit unusual as it uses modules to reuse particular tests in different test cases. The reason for this is that we need to enforce the I18n API across various combinations of extensions. E.g. the Simple backend alone needs to support the same API as any combination of feature and/or optimization modules included to the Simple backend. We test this by reusing the same API defition (implemented as test methods) in test cases with different setups. You can find the test cases that enforce the API in test/api. And you can find the API definition test methods in test/api/tests. All other test cases (e.g. as defined in test/backend, test/core_ext) etc. follow the usual test setup and should be easy to grok. ## Authors * [Sven Fuchs](http://www.artweb-design.de) * [Joshua Harvey](http://www.workingwithrails.com/person/759-joshua-harvey) * [Stephan Soller](http://www.arkanis-development.de) * [Saimon Moore](http://saimonmoore.net) * [Matt Aimonetti](http://railsontherun.com) ## Contributors https://github.com/svenfuchs/i18n/graphs/contributors ## License MIT License. See the included MIT-LICENSE file.