Make parsing locales more robust.

This commit is contained in:
Markus Reiter 2016-10-07 20:03:50 +02:00
parent 7af8cdcb04
commit fca66e17b3
2 changed files with 23 additions and 12 deletions

View File

@ -1,20 +1,28 @@
class Locale class Locale
class ParserError < ::RuntimeError class ParserError < StandardError
end end
LANGUAGE_REGEX = /(?:[a-z]{2})/ LANGUAGE_REGEX = /(?:[a-z]{2,3})/ # ISO 639-1 or ISO 639-2
REGION_REGEX = /(?:[A-Z]{2})/ REGION_REGEX = /(?:[A-Z]{2})/ # ISO 3166-1
SCRIPT_REGEX = /(?:[A-Z][a-z]{3})/ SCRIPT_REGEX = /(?:[A-Z][a-z]{3})/ # ISO 15924
LOCALE_REGEX = /^(#{LANGUAGE_REGEX})?(?:(?:^|-)(#{REGION_REGEX}))?(?:(?:^|-)(#{SCRIPT_REGEX}))?$/ LOCALE_REGEX = /\A((?:#{LANGUAGE_REGEX}|#{REGION_REGEX}|#{SCRIPT_REGEX})(?:\-|$)){1,3}\Z/
def self.parse(string) def self.parse(string)
language, region, script = string.to_s.scan(LOCALE_REGEX)[0] string = string.to_s
if language.nil? && region.nil? && script.nil? if string !~ LOCALE_REGEX
raise ParserError, "'#{string}' cannot be parsed to a #{self.class}" raise ParserError, "'#{string}' cannot be parsed to a #{self}"
end end
scan = proc do |regex|
string.scan(/(?:\-|^)(#{regex})(?:\-|$)/).flatten.first
end
language = scan.call(LANGUAGE_REGEX)
region = scan.call(REGION_REGEX)
script = scan.call(SCRIPT_REGEX)
new(language, region, script) new(language, region, script)
end end

View File

@ -1,16 +1,19 @@
require "testing_env" require "testing_env"
require "locale"
require "os/mac" require "os/mac"
class OSMacLanguageTests < Homebrew::TestCase class OSMacLanguageTests < Homebrew::TestCase
LANGUAGE_REGEX = /\A[a-z]{2}(-[A-Z]{2})?(-[A-Z][a-z]{3})?\Z/
def test_languages_format def test_languages_format
OS::Mac.languages.each do |language| OS::Mac.languages.each do |language|
assert_match LANGUAGE_REGEX, language assert_nothing_raised do
Locale.parse(language)
end
end end
end end
def test_language_format def test_language_format
assert_match LANGUAGE_REGEX, OS::Mac.language assert_nothing_raised do
Locale.parse(OS::Mac.language)
end
end end
end end