Skip to content

Commit

Permalink
refactor Globalize::Locale::Rfc4646 and add Globalize::Locale::Langua…
Browse files Browse the repository at this point in the history
…geTag
  • Loading branch information
Sven Fuchs committed Sep 11, 2008
1 parent c0a2038 commit 2fb99d0
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 45 deletions.
4 changes: 2 additions & 2 deletions lib/globalize/locale/fallbacks.rb
@@ -1,4 +1,4 @@
require 'globalize/locale/rfc4646'
require 'globalize/locale/language_tag'

module Globalize
module Locale
Expand All @@ -9,7 +9,7 @@ def initialize(rules = nil)

# TODO make this code handle real cases
def compute(tag)
rfc_tag = Rfc4646::tag(tag)
rfc_tag = LanguageTag::tag(tag)
[ rfc_tag, rfc_tag.parent ].compact.map {|rt| rt.to_s } + (@map[tag] || [])
end

Expand Down
@@ -1,14 +1,18 @@
# TODO rename this according to http://en.wikipedia.org/wiki/IETF_language_tag
# for specifications see http://en.wikipedia.org/wiki/IETF_language_tag
#
# SimpleParser does not implement advanced usages such as grandfathered tags

module Globalize
module Locale
module Rfc4646
SUBTAGS = [:language, :script, :region, :variant, :extension, :privateuse, :grandfathered]
FORMATS = {:language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase}

end

class LanguageTag < Struct.new(*Rfc4646::SUBTAGS)
class << self
def parser
@@parser ||= Simple
@@parser ||= SimpleParser
end

def parser=(parser)
Expand All @@ -17,30 +21,28 @@ def parser=(parser)

def tag(tag)
matches = parser.match(tag)
Tag.new *matches if matches
new *matches if matches
end
end

class Tag < Struct.new(*SUBTAGS)
FORMATS.each do |name, format|
define_method(name) { self[name].send(format) unless self[name].nil? }
end

def to_s
@tag ||= to_a.compact.join("-")
end

def to_a
members.collect {|attr| self.send(attr) }
end

def parent
segs = to_a.compact
segs.length < 2 ? nil : Rfc4646.tag(segs[0..(segs.length-2)].join('-'))
end
Rfc4646::FORMATS.each do |name, format|
define_method(name) { self[name].send(format) unless self[name].nil? }
end

def to_s
@tag ||= to_a.compact.join("-")
end

def to_a
members.collect {|attr| self.send(attr) }
end

def parent
segs = to_a.compact
segs.length < 2 ? nil : LanguageTag.tag(segs[0..(segs.length-2)].join('-'))
end

module Simple
module SimpleParser
PATTERN = %r{\A(?:
([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language
(?:-([a-z]{4}))? # script
Expand Down
2 changes: 1 addition & 1 deletion spec/locale/fallbacks_spec.rb
@@ -1,6 +1,6 @@
require File.dirname(__FILE__) + '/../spec/helper.rb'
require 'globalize/locale/fallbacks'
require 'globalize/locale/rfc4646'
require 'globalize/locale/language_tag'

include Globalize::Locale

Expand Down
40 changes: 20 additions & 20 deletions spec/locale/rfc4646_spec.rb → spec/locale/language_tag_spec.rb
Expand Up @@ -2,42 +2,42 @@

include Globalize::Locale

describe Globalize::Locale::Rfc4646 do
it "given a valid tag 'de' returns an Rfc4646::Tag from #tag" do
Rfc4646.tag('de').should be_instance_of(Rfc4646::Tag)
describe Globalize::Locale::LanguageTag do
it "given a valid tag 'de' returns an LanguageTag from #tag" do
LanguageTag.tag('de').should be_instance_of(LanguageTag)
end
end

describe Rfc4646::Simple, '#match' do
describe LanguageTag::SimpleParser, '#match' do
it "given a valid tag 'de' returns an array of subtags" do
Rfc4646::Simple.match('de').should == ['de', nil, nil, nil, nil, nil, nil]
LanguageTag::SimpleParser.match('de').should == ['de', nil, nil, nil, nil, nil, nil]
end

it "given a valid tag 'de' returns an array of subtags" do
Rfc4646::Simple.match('de-DE').should == ['de', nil, 'DE', nil, nil, nil, nil]
LanguageTag::SimpleParser.match('de-DE').should == ['de', nil, 'DE', nil, nil, nil, nil]
end

it "given a valid lowercase tag 'de-latn-de-variant-x-phonebk' returns an array of subtags" do
Rfc4646::Simple.match('de-latn-de-variant-x-phonebk').should == ['de', 'latn', 'de', 'variant', nil, 'x-phonebk', nil]
LanguageTag::SimpleParser.match('de-latn-de-variant-x-phonebk').should == ['de', 'latn', 'de', 'variant', nil, 'x-phonebk', nil]
end

it "given a valid uppercase tag 'DE-LATN-DE-VARIANT-X-PHONEBK' returns an array of subtags" do
Rfc4646::Simple.match('DE-LATN-DE-VARIANT-X-PHONEBK').should == ['DE', 'LATN', 'DE', 'VARIANT', nil, 'X-PHONEBK', nil]
LanguageTag::SimpleParser.match('DE-LATN-DE-VARIANT-X-PHONEBK').should == ['DE', 'LATN', 'DE', 'VARIANT', nil, 'X-PHONEBK', nil]
end

it "given an invalid tag 'a-DE' it returns false" do
Rfc4646::Simple.match('a-DE').should == false
LanguageTag::SimpleParser.match('a-DE').should == false
end

it "given an invalid tag 'de-419-DE' it returns false" do
Rfc4646::Simple.match('de-419-DE').should == false
LanguageTag::SimpleParser.match('de-419-DE').should == false
end
end

describe "Rfc4646::Tag for the locale 'DE-latn-de-Variant-a-ext-x-phonebk-i-klingon'" do
describe "LanguageTag for the locale 'DE-latn-de-Variant-a-ext-x-phonebk-i-klingon'" do
before :each do
subtags = %w(de Latn DE variant a-ext x-phonebk i-klingon)
@tag = Rfc4646::Tag.new *subtags
@tag = LanguageTag.new *subtags
end

it "returns 'de' as the language subtag in lowercase" do
Expand Down Expand Up @@ -77,41 +77,41 @@
end
end

describe "Rfc4646::Tag inheritance" do
describe "LanguageTag inheritance" do
it "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 = Rfc4646::Tag.new *%w(de Latn DE variant a-ext x-phonebk i-klingon)
tag = LanguageTag.new *%w(de Latn DE variant a-ext x-phonebk i-klingon)
tag.parent.to_s.should == 'de-Latn-DE-variant-a-ext-x-phonebk'
end

it "returns 'de-Latn-DE-variant-a-ext' as the parent of 'de-Latn-DE-variant-a-ext-x-phonebk'" do
tag = Rfc4646::Tag.new *%w(de Latn DE variant a-ext x-phonebk)
tag = LanguageTag.new *%w(de Latn DE variant a-ext x-phonebk)
tag.parent.to_s.should == 'de-Latn-DE-variant-a-ext'
end

it "returns 'de-Latn-DE-variant' as the parent of 'de-Latn-DE-variant-a-ext'" do
tag = Rfc4646::Tag.new *%w(de Latn DE variant a-ext)
tag = LanguageTag.new *%w(de Latn DE variant a-ext)
tag.parent.to_s.should == 'de-Latn-DE-variant'
end

it "returns 'de-Latn-DE' as the parent of 'de-Latn-DE-variant'" do
tag = Rfc4646::Tag.new *%w(de Latn DE variant)
tag = LanguageTag.new *%w(de Latn DE variant)
tag.parent.to_s.should == 'de-Latn-DE'
end

it "returns 'de-Latn' as the parent of 'de-Latn-DE'" do
tag = Rfc4646::Tag.new *%w(de Latn DE)
tag = LanguageTag.new *%w(de Latn DE)
tag.parent.to_s.should == 'de-Latn'
end

it "returns 'de' as the parent of 'de-Latn'" do
tag = Rfc4646::Tag.new *%w(de Latn)
tag = LanguageTag.new *%w(de Latn)
tag.parent.to_s.should == 'de'
end

# TODO RFC4647 says: "If no language tag matches the request, the "default" value is returned."
# where should we set the default language?
# it "returns '' as the parent of 'de'" do
# tag = Rfc4646::Tag.new *%w(de)
# tag = LanguageTag.new *%w(de)
# tag.parent.to_s.should == ''
# end
end

0 comments on commit 2fb99d0

Please sign in to comment.