Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

add and adapt Globalize2 fallback implementation

  • Loading branch information...
commit 1b37a303b27d6222b17162804b06323e5628768f 1 parent 32ddc80
Sven Fuchs authored
18 lib/i18n/backend/fallbacks.rb
View
@@ -0,0 +1,18 @@
+require 'i18n/backend/simple'
+require 'i18n/locale/fallbacks'
+
+module I18n
+ module Backend
+ module Fallbacks
+ def translate(locale, key, options = {})
+ I18n.fallbacks[locale].each do |fallback|
+ begin
+ result = super(fallback, key, options) and return result
+ rescue I18n::MissingTranslationData
+ end
+ end
+ raise(I18n::MissingTranslationData.new(locale, key, options))
+ end
+ end
+ end
+end
75 lib/i18n/locale/fallbacks.rb
View
@@ -0,0 +1,75 @@
+require 'i18n/locale/tag'
+
+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 differen fallbacks implementation.
+ def fallbacks=(fallbacks)
+ @@fallbacks = fallbacks
+ end
+
+ # Locale tag factory. Uses I18n::Locale::Tag by default.
+ def tag(tag)
+ tags.tag(tag.to_sym)
+ end
+
+ def tags
+ @@tags ||= I18n::Locale::Tag
+ end
+
+ def tags=(tag_class)
+ @@tags = tag_class
+ end
+ end
+
+ module Locale
+ class Fallbacks < Hash
+ def initialize(*defaults)
+ @map = {}
+ map defaults.pop if defaults.last.is_a?(Hash)
+
+ defaults = [I18n.default_locale.to_sym] if defaults.empty?
+ self.defaults = defaults
+ 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
+ has_key?(locale) ? fetch(locale) : 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)
+ result = Array(tags).collect do |tag|
+ tags = I18n.tag(tag).self_and_parents.map! { |t| t.to_sym }
+ tags.each { |tag| tags += compute(@map[tag]) if @map[tag] }
+ tags
+ end.flatten
+ result.push(*defaults) if include_defaults
+ result.uniq
+ end
+ end
+ end
+end
26 lib/i18n/locale/tag.rb
View
@@ -0,0 +1,26 @@
+# for specifications see http://en.wikipedia.org/wiki/IETF_language_tag
+#
+# SimpleParser does not implement advanced usages such as grandfathered tags
+
+require 'i18n/locale/tag/basic'
+require 'i18n/locale/tag/rfc4646'
+
+module I18n
+ module Locale
+ module Tag
+ class << self
+ def implementation
+ @@implementation ||= Rfc4646
+ end
+
+ def implementation=(implementation)
+ @@implementation = implementation
+ end
+
+ def tag(tag)
+ implementation.tag(tag)
+ end
+ end
+ end
+ end
+end
39 lib/i18n/locale/tag/basic.rb
View
@@ -0,0 +1,39 @@
+require 'i18n/locale/tag/parents'
+
+module I18n
+ module Locale
+ module Tag
+ class Basic
+ 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
22 lib/i18n/locale/tag/parents.rb
View
@@ -0,0 +1,22 @@
+module 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
71 lib/i18n/locale/tag/rfc4646.rb
View
@@ -0,0 +1,71 @@
+# for specifications see http://en.wikipedia.org/wiki/IETF_language_tag
+#
+# Rfc4646::Parser does not implement advanced usages such as grandfathered tags
+
+require 'i18n/locale/tag/parents'
+
+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
+ def parser
+ @@parser ||= Rfc4646::Parser
+ end
+
+ def parser=(parser)
+ @@parser = parser
+ end
+
+ def tag(tag)
+ matches = parser.match(tag)
+ new(*matches) if matches
+ 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
59 test/backend/fallbacks/api_test.rb
View
@@ -0,0 +1,59 @@
+require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
+require 'i18n/backend/fallbacks'
+
+# class I18nFallbacksBackendApiBasicsTest < Test::Unit::TestCase
+# include Tests::Backend::Simple::Setup::Base
+# include Tests::Backend::Fallbacks::Setup
+# include Tests::Backend::Api::Basics
+# end
+
+class I18nFallbacksBackendApiTranslateTest < Test::Unit::TestCase
+ include Tests::Backend::Simple::Setup::Base
+ include Tests::Backend::Fallbacks::Setup
+ include Tests::Backend::Api::Translation
+end
+
+# class I18nFallbacksBackendApiInterpolateTest < Test::Unit::TestCase
+# include Tests::Backend::Simple::Setup::Base
+# include Tests::Backend::Fallbacks::Setup
+# include Tests::Backend::Api::Interpolation
+# end
+#
+# class I18nFallbacksBackendApiLambdaTest < Test::Unit::TestCase
+# include Tests::Backend::Simple::Setup::Base
+# include Tests::Backend::Fallbacks::Setup
+# include Tests::Backend::Api::Lambda
+# end
+#
+# class I18nFallbacksBackendApiTranslateLinkedTest < Test::Unit::TestCase
+# include Tests::Backend::Simple::Setup::Base
+# include Tests::Backend::Fallbacks::Setup
+# include Tests::Backend::Api::Link
+# end
+#
+# class I18nFallbacksBackendApiPluralizationTest < Test::Unit::TestCase
+# include Tests::Backend::Simple::Setup::Base
+# include Tests::Backend::Fallbacks::Setup
+# include Tests::Backend::Api::Pluralization
+# end
+
+# class I18nFallbacksBackendApiLocalizeDateTest < Test::Unit::TestCase
+# include Tests::Backend::Fallbacks::Setup::Localization
+# include Tests::Backend::Api::Localization::Date
+# end
+#
+# class I18nFallbacksBackendApiLocalizeDateTimeTest < Test::Unit::TestCase
+# include Tests::Backend::Fallbacks::Setup::Localization
+# include Tests::Backend::Api::Localization::DateTime
+# end
+#
+# class I18nFallbacksBackendApiLocalizeTimeTest < Test::Unit::TestCase
+# include Tests::Backend::Fallbacks::Setup::Localization
+# include Tests::Backend::Api::Localization::Time
+# end
+#
+# class I18nFallbacksBackendApiLocalizeLambdaTest < Test::Unit::TestCase
+# include Tests::Backend::Fallbacks::Setup::Localization
+# include Tests::Backend::Api::Localization::Lambda
+# end
+
14 test/backend/fallbacks/setup.rb
View
@@ -0,0 +1,14 @@
+module Tests
+ module Backend
+ module Fallbacks
+ module Setup
+ def setup
+ super
+ class << I18n.backend
+ include I18n::Backend::Fallbacks
+ end
+ end
+ end
+ end
+ end
+end
20 test/backend/simple/api_test.rb
View
@@ -1,12 +1,12 @@
# encoding: utf-8
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
-class I18nSimpleBackendApiTest < Test::Unit::TestCase
+class I18nSimpleBackendApiBasicsTest < Test::Unit::TestCase
include Tests::Backend::Simple::Setup::Base
include Tests::Backend::Api::Basics
end
-class I18nSimpleBackendTranslateTest < Test::Unit::TestCase
+class I18nSimpleBackendApiTranslateTest < Test::Unit::TestCase
include Tests::Backend::Simple::Setup::Base
include Tests::Backend::Api::Translation
@@ -33,7 +33,7 @@ def test_translate_calls_interpolate_including_count_as_a_value
end
end
-class I18nSimpleBackendInterpolateTest < Test::Unit::TestCase
+class I18nSimpleBackendApiInterpolateTest < Test::Unit::TestCase
include Tests::Backend::Simple::Setup::Base
include Tests::Backend::Api::Interpolation
@@ -48,37 +48,37 @@ def test_interpolate_given_an_non_string_as_a_string_returns_nil
end
end
-class I18nSimpleBackendLambdaTest < Test::Unit::TestCase
+class I18nSimpleBackendApiLambdaTest < Test::Unit::TestCase
include Tests::Backend::Simple::Setup::Base
include Tests::Backend::Api::Lambda
end
-class I18nSimpleBackendTranslateLinkedTest < Test::Unit::TestCase
+class I18nSimpleBackendApiTranslateLinkedTest < Test::Unit::TestCase
include Tests::Backend::Simple::Setup::Base
include Tests::Backend::Api::Link
end
-class I18nSimpleBackendPluralizationTest < Test::Unit::TestCase
+class I18nSimpleBackendApiPluralizationTest < Test::Unit::TestCase
include Tests::Backend::Simple::Setup::Base
include Tests::Backend::Api::Pluralization
end
-class I18nSimpleBackendLocalizeDateTest < Test::Unit::TestCase
+class I18nSimpleBackendApiLocalizeDateTest < Test::Unit::TestCase
include Tests::Backend::Simple::Setup::Localization
include Tests::Backend::Api::Localization::Date
end
-class I18nSimpleBackendLocalizeDateTimeTest < Test::Unit::TestCase
+class I18nSimpleBackendApiLocalizeDateTimeTest < Test::Unit::TestCase
include Tests::Backend::Simple::Setup::Localization
include Tests::Backend::Api::Localization::DateTime
end
-class I18nSimpleBackendLocalizeTimeTest < Test::Unit::TestCase
+class I18nSimpleBackendApiLocalizeTimeTest < Test::Unit::TestCase
include Tests::Backend::Simple::Setup::Localization
include Tests::Backend::Api::Localization::Time
end
-class I18nSimpleBackendLocalizeLambdaTest < Test::Unit::TestCase
+class I18nSimpleBackendApiLocalizeLambdaTest < Test::Unit::TestCase
include Tests::Backend::Simple::Setup::Localization
include Tests::Backend::Api::Localization::Lambda
end
36 test/backend/simple/setup/localization.rb → test/backend/simple/setup.rb
View
@@ -2,6 +2,22 @@ module Tests
module Backend
module Simple
module Setup
+ module Base
+ def setup
+ super
+ I18n.backend = I18n::Backend::Simple.new
+ backend_store_translations :en, :foo => {:bar => 'bar', :baz => 'baz'}
+ end
+
+ def teardown
+ super
+ I18n.load_path = []
+ I18n.backend = nil
+ I18n.locale = nil
+ I18n.default_locale = :en
+ end
+ end
+
module Localization
include Base
@@ -11,12 +27,12 @@ def setup
setup_datetime_lambda_translations
@old_timezone, ENV['TZ'] = ENV['TZ'], 'UTC'
end
-
+
def teardown
super
@old_timezone ? ENV['TZ'] = @old_timezone : ENV.delete('TZ')
end
-
+
def setup_datetime_translations
backend_store_translations :de, {
:date => {
@@ -99,19 +115,19 @@ def setup_datetime_translations
def setup_datetime_lambda_translations
backend_store_translations 'ru', {
:date => {
- :'day_names' => lambda { |key, options|
- (options[:format] =~ /^%A/) ?
- %w(Воскресенье Понедельник Вторник Среда Четверг Пятница Суббота) :
+ :'day_names' => lambda { |key, options|
+ (options[:format] =~ /^%A/) ?
+ %w(Воскресенье Понедельник Вторник Среда Четверг Пятница Суббота) :
%w(воскресенье понедельник вторник среда четверг пятница суббота)
},
:'abbr_day_names' => %w(Вс Пн Вт Ср Чт Пт Сб),
- :'month_names' => lambda { |key, options|
- (options[:format] =~ /(%d|%e)(\s*)?(%B)/) ?
+ :'month_names' => lambda { |key, options|
+ (options[:format] =~ /(%d|%e)(\s*)?(%B)/) ?
%w(января февраля марта апреля мая июня июля августа сентября октября ноября декабря).unshift(nil) :
- %w(Январь Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь).unshift(nil)
+ %w(Январь Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь).unshift(nil)
},
- :'abbr_month_names' => lambda { |key, options|
- (options[:format] =~ /(%d|%e)(\s*)(%b)/) ?
+ :'abbr_month_names' => lambda { |key, options|
+ (options[:format] =~ /(%d|%e)(\s*)(%b)/) ?
%w(янв. февр. марта апр. мая июня июля авг. сент. окт. нояб. дек.).unshift(nil) :
%w(янв. февр. март апр. май июнь июль авг. сент. окт. нояб. дек.).unshift(nil)
},
21 test/backend/simple/setup/base.rb
View
@@ -1,21 +0,0 @@
-module Tests
- module Backend
- module Simple
- module Setup
- module Base
- def setup
- super
- I18n.backend = I18n::Backend::Simple.new
- backend_store_translations :en, :foo => {:bar => 'bar', :baz => 'baz'}
- end
-
- def teardown
- super
- I18n.load_path = []
- I18n.backend = nil
- end
- end
- end
- end
- end
-end
126 test/locale/fallbacks_test.rb
View
@@ -0,0 +1,126 @@
+require File.dirname(__FILE__) + '/../test_helper.rb'
+require 'i18n/locale/fallbacks'
+require 'i18n/locale/tag'
+
+include I18n::Locale
+
+class I18nFallbacksDefaultsTest < Test::Unit::TestCase
+ def teardown
+ I18n.default_locale = :en
+ end
+
+ test "defaults reflect the I18n.default_locale if no default has been set manually" do
+ I18n.default_locale = :'en-US'
+ I18n.fallbacks = Fallbacks.new
+ assert_equal [:'en-US', :en], I18n.fallbacks.defaults
+ end
+
+ test "defaults reflect a manually passed default locale if any" do
+ I18n.fallbacks = Fallbacks.new(:'fi-FI')
+ assert_equal [:'fi-FI', :fi], I18n.fallbacks.defaults
+ I18n.default_locale = :'de-DE'
+ assert_equal [:'fi-FI', :fi], I18n.fallbacks.defaults
+ end
+
+ test "defaults allows to set multiple defaults" do
+ I18n.fallbacks = Fallbacks.new(:'fi-FI', :'se-FI')
+ assert_equal [:'fi-FI', :fi, :'se-FI', :se], I18n.fallbacks.defaults
+ end
+end
+
+class I18nFallbacksComputationTest < Test::Unit::TestCase
+ def setup
+ @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
+end
115 test/locale/tag/basic_test.rb
View
@@ -0,0 +1,115 @@
+require File.dirname(__FILE__) + '/../../test_helper.rb'
+require 'i18n/locale/tag'
+require 'i18n/locale/tag/basic'
+
+# Tag for the locale 'DE-latn-de'
+
+class I18nLocaleTagSubtagsTest < Test::Unit::TestCase
+ include I18n::Locale
+
+ def setup
+ subtags = %w(de Latn DE)
+ @tag = Tag::Basic.new *subtags
+ end
+
+ test "returns 'de' as the language subtag in lowercase" do
+ assert_equal %w(de Latn DE), @tag.subtags
+ 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 < Test::Unit::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::Basic.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::Basic.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::Basic.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::Basic.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::Basic.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::Basic.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::Basic.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::Basic.new *%w(de Latn DE variant a-ext x-phonebk i-klingon)
+# assert_equal parents, tag.self_and_parents.map{|tag| tag.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::Basic.new *%w(de Latn DE variant a-ext x-phonebk i-klingon)
+# assert_equal parents, tag.self_and_parents.map{|tag| tag.to_s}
+# end
+# end
145 test/locale/tag/rfc4646_test.rb
View
@@ -0,0 +1,145 @@
+require File.dirname(__FILE__) + '/../../test_helper.rb'
+require 'i18n/locale/tag'
+require 'i18n/locale/tag/rfc4646'
+
+# Rfc4646::Parser
+
+class I18nLocaleTagRfc4646ParserTest < Test::Unit::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' 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 < Test::Unit::TestCase
+ include I18n::Locale
+
+ def setup
+ 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 < Test::Unit::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{|tag| tag.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{|tag| tag.to_s}
+ end
+end
9 test/test_helper.rb
View
@@ -9,8 +9,8 @@
require 'yaml'
require File.dirname(__FILE__) + '/with_options'
-require File.dirname(__FILE__) + '/backend/simple/setup/base'
-require File.dirname(__FILE__) + '/backend/simple/setup/localization'
+require File.dirname(__FILE__) + '/backend/simple/setup'
+require File.dirname(__FILE__) + '/backend/fallbacks/setup'
Dir[File.dirname(__FILE__) + '/api/**/*.rb'].each do |filename|
require filename
@@ -18,7 +18,12 @@
$KCODE = 'u' unless RUBY_VERSION >= '1.9'
+
class Test::Unit::TestCase
+ def self.test(name, &block)
+ define_method("test: " + name, &block)
+ end
+
def euc_jp(string)
string.encode!(Encoding::EUC_JP)
end
Please sign in to comment.
Something went wrong with that request. Please try again.