Skip to content
Snippets Groups Projects
Commit b5531e8e authored by Markus Reiter's avatar Markus Reiter
Browse files

Add Locale class to enable easier matching of locales.

parent bc143bb4
No related branches found
No related tags found
No related merge requests found
require "spec_helper"
require "locale"
describe Locale do
describe "::parse" do
it "parses a string in the correct format" do
expect(described_class.parse("zh")).to eql(described_class.new("zh", nil, nil))
expect(described_class.parse("zh-CN")).to eql(described_class.new("zh", "CN", nil))
expect(described_class.parse("zh-Hans")).to eql(described_class.new("zh", nil, "Hans"))
expect(described_class.parse("zh-CN-Hans")).to eql(described_class.new("zh", "CN", "Hans"))
end
context "raises a ParserError when given" do
it "an empty string" do
expect{ described_class.parse("") }.to raise_error(Locale::ParserError)
end
it "a string in a wrong format" do
expect { described_class.parse("zh_CN_Hans") }.to raise_error(Locale::ParserError)
expect { described_class.parse("zhCNHans") }.to raise_error(Locale::ParserError)
expect { described_class.parse("zh-CN_Hans") }.to raise_error(Locale::ParserError)
expect { described_class.parse("zhCN") }.to raise_error(Locale::ParserError)
expect { described_class.parse("zh_Hans") }.to raise_error(Locale::ParserError)
end
end
end
describe "::new" do
it "raises an ArgumentError when all arguments are nil" do
expect { described_class.new(nil, nil, nil) }.to raise_error(ArgumentError)
end
it "raises a ParserError when one of the arguments does not match the locale format" do
expect { described_class.new("ZH", nil, nil) }.to raise_error(Locale::ParserError)
expect { described_class.new(nil, "cn", nil) }.to raise_error(Locale::ParserError)
expect { described_class.new(nil, nil, "hans") }.to raise_error(Locale::ParserError)
end
end
subject { described_class.new("zh", "CN", "Hans") }
describe "#include?" do
it { is_expected.to include("zh") }
it { is_expected.to include("zh-CN") }
it { is_expected.to include("CN") }
it { is_expected.to include("CN-Hans") }
it { is_expected.to include("Hans") }
it { is_expected.to include("zh-CN-Hans") }
end
describe "#eql?" do
subject { described_class.new("zh", "CN", "Hans") }
context "all parts match" do
it { is_expected.to eql("zh-CN-Hans") }
it { is_expected.to eql(subject) }
end
context "only some parts match" do
it { is_expected.to_not eql("zh") }
it { is_expected.to_not eql("zh-CN") }
it { is_expected.to_not eql("CN") }
it { is_expected.to_not eql("CN-Hans") }
it { is_expected.to_not eql("Hans") }
end
it "does not raise if 'other' cannot be parsed" do
expect { subject.eql?("zh_CN_Hans") }.not_to raise_error
expect(subject.eql?("zh_CN_Hans")).to be false
end
end
end
class Locale
class ParserError < ::RuntimeError
end
LANGUAGE_REGEX = /(?:[a-z]{2})/
REGION_REGEX = /(?:[A-Z]{2})/
SCRIPT_REGEX = /(?:[A-Z][a-z]{3})/
LOCALE_REGEX = /^(#{LANGUAGE_REGEX})?(?:(?:^|-)(#{REGION_REGEX}))?(?:(?:^|-)(#{SCRIPT_REGEX}))?$/
def self.parse(string)
language, region, script = string.to_s.scan(LOCALE_REGEX)[0]
if language.nil? && region.nil? && script.nil?
raise ParserError, "'#{string}' cannot be parsed to a #{self.class}"
end
new(language, region, script)
end
attr_reader :language, :region, :script
def initialize(language, region, script)
if language.nil? && region.nil? && script.nil?
raise ArgumentError, "#{self.class} cannot be empty"
end
{
language: language,
region: region,
script: script,
}.each do |key, value|
next if value.nil?
regex = self.class.const_get("#{key.upcase}_REGEX")
raise ParserError, "'#{value}' does not match #{regex}" unless value =~ regex
instance_variable_set(:"@#{key}", value)
end
self
end
def include?(other)
other = self.class.parse(other) unless other.is_a?(self.class)
[:language, :region, :script].all? { |var|
if other.public_send(var).nil?
true
else
public_send(var) == other.public_send(var)
end
}
end
def eql?(other)
other = self.class.parse(other) unless other.is_a?(self.class)
[:language, :region, :script].all? { |var|
public_send(var) == other.public_send(var)
}
rescue ParserError
false
end
alias == eql?
def to_s
[@language, @region, @script].compact.join("-")
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment