def test_errors_multiple_script_subtags(self): tag = Tag('mt-Arab-Arab') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_EXTRA_SCRIPT) self.assertEqual(err.message, 'Extra script subtag \'Arab\' found.') tag = Tag('en-Cyrl-Latn') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_EXTRA_SCRIPT) self.assertEqual(err.message, 'Extra script subtag \'Latn\' found.') # First error should be regarding suppress-script, second should be regarding extra script. tag = Tag('en-Latn-Cyrl') errs = tag.errors self.assertEqual(len(errs), 2) err = errs[0] self.assertEqual(err.code, tag.ERR_SUPPRESS_SCRIPT) self.assertEqual( err.message, 'The script subtag \'Latn\' is the same as the language suppress-script.' ) err = errs[1] self.assertEqual(err.code, tag.ERR_EXTRA_SCRIPT) self.assertEqual(err.message, 'Extra script subtag \'Cyrl\' found.')
def test_perferred(self): tag = Tag('zh-cmn-Hant') self.assertEqual(tag.type, 'redundant') self.assertIsNotNone(tag.deprecated) self.assertIsNotNone(tag.preferred) self.assertEqual(tag.preferred.format, 'cmn-Hant') self.assertIsNone(Tag('cmn-Hant').preferred)
def test_subtags_correct_type(self): tag = Tag('aa') subtags = tag.subtags self.assertEqual(len(subtags), 1) self.assertEqual(subtags[0].type, 'language') self.assertEqual(subtags[0].format, 'aa') # Lowercase - lookup should be case insensitive. tag = Tag('en-mt') subtags = tag.subtags self.assertEqual(len(subtags), 2) self.assertEqual(subtags[0].type, 'language') self.assertEqual(subtags[0].format, 'en') self.assertEqual(subtags[1].type, 'region') self.assertEqual(subtags[1].format, 'MT') tag = Tag('en-mt-arab') subtags = tag.subtags self.assertEqual(len(subtags), 3) self.assertEqual(subtags[0].type, 'language') self.assertEqual(subtags[0].format, 'en') self.assertEqual(subtags[1].type, 'region') self.assertEqual(subtags[1].format, 'MT') self.assertEqual(subtags[2].type, 'script') self.assertEqual(subtags[2].format, 'Arab')
def test_valid_tag(self): self.assertTrue(Tag('en').valid) self.assertTrue(Tag('en-GB').valid) self.assertTrue(Tag('gsw').valid) self.assertTrue(Tag('de-CH').valid) # returns true for subtag followed by private tag self.assertTrue(Tag('en-x-whatever').valid)
def test_description(self): tag = Tag('en-GB-oed') self.assertEqual(tag.type, 'grandfathered') self.assertEqual('2015-04-17', tag.deprecated) self.assertEqual(tag.descriptions, ['English, Oxford English Dictionary spelling']) self.assertEqual(Tag('en').descriptions, [])
def test_only_existent_subtags(self): tag = Tag('hello') self.assertEqual(tag.subtags, []) tag = Tag('en-hello') subtags = tag.subtags self.assertEqual(len(subtags), 1) self.assertEqual(subtags[0].type, 'language') self.assertEqual(subtags[0].format, 'en')
def test_valid_tag_redundant(self): # Redundant but not deprecated, therefore valid. tag = Tag('zh-Hans') self.assertEqual(tag.type, 'redundant') self.assertIsNone(tag.deprecated) self.assertTrue(tag.valid) tag = Tag('es-419') self.assertEqual(tag.type, 'redundant') self.assertIsNone(tag.deprecated) self.assertTrue(tag.valid)
def test_non_valid_deprecated_redundant(self): # Redundant and deprecated, therefore invalid. tag = Tag('zh-cmn') self.assertEqual(tag.type, 'redundant') self.assertIsNotNone(tag.deprecated) self.assertFalse(tag.valid) tag = Tag('zh-cmn-Hans') self.assertEqual(tag.type, 'redundant') self.assertIsNotNone(tag.deprecated) self.assertFalse(tag.valid)
def test_errors_length_private_use_subtags(self): tag = Tag('en-x-more-than-eight-chars') errs = tag.errors self.assertEqual(len(errs), 0) tag = Tag('en-x-morethaneightchars') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_TOO_LONG) self.assertEqual( err.message, 'The private-use subtag \'morethaneightchars\' is too long.')
def test_errors_multiple_region_subtags(self): tag = Tag('en-GB-GB') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_EXTRA_REGION) self.assertEqual(err.message, 'Extra region subtag \'GB\' found.') tag = Tag('ko-mt-mt') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_EXTRA_REGION) self.assertEqual(err.message, 'Extra region subtag \'MT\' found.')
def test_format(self): self.assertEqual(Tag('en').format, 'en') self.assertEqual( Tag('en-x-more-than-eight-chars').format, 'en-x-more-than-eight-chars') self.assertEqual(Tag('En').format, 'en') self.assertEqual(Tag('EN').format, 'en') self.assertEqual(Tag('eN').format, 'en') self.assertEqual(Tag('en-gb').format, 'en-GB') self.assertEqual(Tag('en-gb-oed').format, 'en-GB-oed') self.assertEqual(Tag('az-latn').format, 'az-Latn') self.assertEqual(Tag('ZH-hant-hK').format, 'zh-Hant-HK')
def test_errors_front_no_language_tag(self): tag = Tag('GB-en') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_NO_LANGUAGE) self.assertEqual(err.message, 'Missing language tag in \'gb-en\'.')
def test_errors_deprecated_subtags(self): # Moldovan (mo) is deprecated as a language. tag = Tag('mo') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_SUBTAG_DEPRECATED) self.assertEqual(err.message, 'The subtag \'mo\' is deprecated.') # Neutral Zone (NT) is deprecated as a region. tag = Tag('en-NT') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_SUBTAG_DEPRECATED) self.assertEqual(err.message, 'The subtag \'NT\' is deprecated.')
def test_errors_multiple_extlang_subtags(self): tag = Tag('en-asp-bog') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_EXTRA_EXTLANG) self.assertEqual(err.message, 'Extra extlang subtag \'bog\' found.')
def test_subtags_of_private_tags(self): tag = Tag('en-GB-x-Beano') subtags = tag.subtags self.assertEqual(len(subtags), 2) self.assertEqual(subtags[0].type, 'language') self.assertEqual(subtags[0].format, 'en') self.assertEqual(subtags[1].type, 'region') self.assertEqual(subtags[1].format, 'GB')
def check(tag): """ Check if a string (hyphen-separated) tag is valid. :param str tag: (hyphen-separated) tag. :return: bool -- True if valid. """ return Tag(tag).valid
def tag(tag): """ Get a :class:`language_tags.Tag.Tag` of a string (hyphen-separated) tag. :param str tag: (hyphen-separated) tag. :return: :class:`language_tags.Tag.Tag`. """ return Tag(tag)
def test_errors_duplicate_variant_subtags(self): tag = Tag('ca-valencia-valencia') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_DUPLICATE_VARIANT) self.assertEqual(err.message, 'Duplicate variant subtag \'valencia\' found.')
def test_errors_wrong_order_subtags(self): tag = Tag('mt-MT-Arab') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_WRONG_ORDER) self.assertEqual( err.message, 'The subtag \'MT\' should not appear before \'Arab\'.')
def test_errors_supress_script(self): tag = Tag('gsw-Latn') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_SUPPRESS_SCRIPT) self.assertEqual( err.message, 'The script subtag \'Latn\' is the same as the language suppress-script.' ) tag = Tag('en-Latn-GB') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_SUPPRESS_SCRIPT) self.assertEqual( err.message, 'The script subtag \'Latn\' is the same as the language suppress-script.' )
def test_errors_deprecated_redundant(self): # Redundant and deprecated, therefore invalid. tag = Tag('zh-cmn') self.assertEqual(tag.type, 'redundant') self.assertIsNotNone(tag.deprecated) errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_DEPRECATED) self.assertEqual(err.tag, 'zh-cmn') self.assertEqual(err.message, 'The tag zh-cmn is deprecated. Use \'cmn\' instead.')
def test_errors_multiple_language_subtags(self): tag = Tag('en-en') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_EXTRA_LANGUAGE) self.assertEqual(err.message, 'Extra language subtag \'en\' found.') tag = Tag('en-en-GB') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_EXTRA_LANGUAGE) self.assertEqual(err.message, 'Extra language subtag \'en\' found.') tag = Tag('ko-en') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_EXTRA_LANGUAGE) self.assertEqual(err.message, 'Extra language subtag \'en\' found.')
def test_deprecated(self): # Redundant and deprecated. tag = Tag('zh-cmn-Hant') self.assertEqual(tag.type, 'redundant') self.assertEqual(tag.deprecated, '2009-07-29') # Redundant but not deprecated. tag = Tag('zh-Hans') self.assertEqual(tag.type, 'redundant') self.assertIsNone(tag.deprecated) # Grandfathered and deprecated. tag = Tag('zh-xiang') self.assertEqual(tag.type, 'grandfathered') self.assertEqual(tag.deprecated, '2009-07-29') # Grandfathered but not deprecated. tag = Tag('i-default') self.assertEqual(tag.type, 'grandfathered') self.assertIsNone(tag.deprecated) self.assertIsNone(Tag('en').deprecated)
def test_errors_no_language_tag(self): # test with empty tag. tag = Tag('') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_NO_LANGUAGE) self.assertEqual(err.message, 'Empty tag.') tag = Tag('IQ-Arab') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_NO_LANGUAGE) self.assertEqual(err.message, 'Missing language tag in \'iq-arab\'.') tag = Tag('419') errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_NO_LANGUAGE) self.assertEqual(err.message, 'Missing language tag in \'419\'.')
def description(tag): """ Gets a list of descriptions given the tag. :param str tag: (hyphen-separated) tag. :return: list of string descriptions. The return list can be empty. """ tag_object = Tag(tag) results = tag_object.descriptions subtags = tag_object.subtags for subtag in subtags: results += subtag.description return results
def test_added(self): # Redundant and deprecated. tag = Tag('zh-cmn-Hant') self.assertEqual(tag.type, 'redundant') self.assertEqual(tag.added, '2005-07-15') # Redundant but not deprecated. tag = Tag('zh-Hans') self.assertEqual(tag.type, 'redundant') self.assertIsNone(tag.deprecated) self.assertEqual(tag.added, '2003-05-30') # Grandfathered and deprecated. tag = Tag('zh-xiang') self.assertEqual(tag.type, 'grandfathered') self.assertEqual(tag.added, '1999-12-18') # Grandfathered but not deprecated. tag = Tag('i-default') self.assertEqual(tag.type, 'grandfathered') self.assertIsNone(tag.deprecated) self.assertEqual(tag.added, '1998-03-10') self.assertIsNone(Tag('en').added)
def test_errors_deprecated_grandfathered(self): # Grandfathered and deprecated, therefore invalid. tag = Tag('art-lojban') self.assertEqual(tag.type, 'grandfathered') self.assertIsNotNone(tag.deprecated) errs = tag.errors self.assertEqual(len(errs), 1) err = errs[0] self.assertEqual(err.code, tag.ERR_DEPRECATED) self.assertEqual(err.tag, 'art-lojban') self.assertEqual( err.message, 'The tag art-lojban is deprecated. Use \'jbo\' instead.') self.assertIn(str(err.code), err.__str__()) self.assertIn(err.message, err.__str__()) self.assertIn(err.tag, err.__str__()) self.assertIn(str(err.subtag), err.__str__())
def search(description, all=False): """ Gets a list of :class:`language_tags.Subtag.Subtag` objects where the description matches. :param description: a string or compiled regular expression. For example: ``search(re.compile('\d{4}'))`` if the description of the returned subtag must contain four contiguous numerical digits. :type description: str or RegExp :param all: If set on True grandfathered and redundant tags will be included in the return list. :type all: bool, optional :return: list of :class:`language_tags.Subtag.Subtag` objects each including the description. The return list can be empty. """ # If the input query is all lowercase, make a case-insensitive match. if isinstance(description, str): list_to_string = lambda l: ', '.join(l).lower( ) if description.lower() == description else ', '.join(l) def test(record): return description in list_to_string(record['Description']) elif hasattr(description.search, '__call__'): def test(record): return description.search(', '.join( record['Description'])) is not None records = filter( lambda r: False if ('Subtag' not in r and not all) else test(r), registry) if six.PY3: records = list(records) # Sort by matched description string length. This is a quick way to push precise matches towards the top. results = sorted(records, key=lambda r: min([abs(len(r_description) - len(description)) for r_description in r['Description']])) \ if isinstance(description, str) else records return [ Subtag(r['Subtag'], r['Type']) if 'Subtag' in r else Tag(['Tag']) for r in results ]
def test_script_subtags(self): self.assertEqual(Tag('en-mt-arab').script.format, 'Arab') self.assertIsNone(Tag('en-mt').script)
def test_region_subtags(self): self.assertEqual(Tag('nl-BE').region.format, 'BE') self.assertIsNone(Tag('nl').region)