Add Locale class to enable easier matching of locales.
This commit is contained in:
parent
bc143bb470
commit
b5531e8ec1
72
Library/Homebrew/cask/spec/locale_spec.rb
Normal file
72
Library/Homebrew/cask/spec/locale_spec.rb
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
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
|
||||||
68
Library/Homebrew/locale.rb
Normal file
68
Library/Homebrew/locale.rb
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
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
|
||||||
Loading…
x
Reference in New Issue
Block a user