public void MostLikely() { Assert.AreEqual("en-Latn-US", LocaleIdentifier.Parse("en").MostLikelySubtags().ToString()); Assert.AreEqual("zh-Hans-CN", LocaleIdentifier.Parse("zh").MostLikelySubtags().ToString()); Assert.AreEqual("zh-Hant-TW", LocaleIdentifier.Parse("zh-TW").MostLikelySubtags().ToString()); Assert.AreEqual("zh-Hans-SG", LocaleIdentifier.Parse("ZH-ZZZZ-SG").MostLikelySubtags().ToString()); }
public void Parsing_Language_Variant() { var id = LocaleIdentifier.Parse("sl-nedis"); Assert.AreEqual("sl", id.Language); Assert.IsTrue(id.Variants.Contains("nedis")); }
public void Parsing_Normalisation() { Assert.AreEqual("en-US", LocaleIdentifier.Parse("eng-840").ToString()); Assert.AreEqual("en-NZ", LocaleIdentifier.Parse("eng-NZ").ToString()); Assert.AreEqual("en-GB", LocaleIdentifier.Parse("en-UK").ToString()); Assert.AreEqual("en-GB", LocaleIdentifier.Parse("eng-UK").ToString()); }
public void Parsing_Language() { var id = LocaleIdentifier.Parse("en"); Assert.AreEqual("en", id.Language); Assert.IsFalse(LocaleIdentifier.TryParse("NotALanguageCode", out id)); }
public void Parsing_Underscore_Separator() { var id = LocaleIdentifier.Parse("zh_Hant_CN"); Assert.AreEqual("zh", id.Language); Assert.AreEqual("Hant", id.Script); Assert.AreEqual("CN", id.Region); }
public void Parsing_Script() { var id = LocaleIdentifier.Parse("Cyrl"); Assert.AreEqual("Cyrl", id.Script); Assert.IsFalse(LocaleIdentifier.TryParse("NotAScript", out id)); }
/// <summary> /// Tries parsing the string representation of a locale identifier. /// </summary> /// <param name="s"> /// A case insensitive string containing a locale identifier, based on BCP47. /// </param> /// <param name="result"> /// A local identifier that refers to <paramref name="s"/> or <b>null</b> if the parsing /// failed. /// </param> /// <param name="message"> /// The reason why the parsing failed. /// </param> /// <returns> /// <b>true</b> if <paramref name="s"/> was parsed successfully; otherwise, <b>false</b>. /// </returns> /// <remarks> /// A locale identifier that refers to <paramref name="s"/>. /// </remarks> public static bool TryParse(string s, out LocaleIdentifier result, out string message) { if (TryParseBcp47(s, out result, out message)) { message = result.TransformFromBcp47(); } return(message == null); }
public void SearchChain_root() { var id = LocaleIdentifier.Parse("root"); var chain = id.SearchChain().ToArray(); Assert.AreEqual(1, chain.Length); Assert.AreEqual("root", chain[0]); }
public void Parsing_Language_Region_Variant() { var id = LocaleIdentifier.Parse("de-CH-1996"); Assert.AreEqual("de", id.Language); Assert.AreEqual("CH", id.Region); Assert.IsTrue(id.Variants.Contains("1996")); }
/// <summary> /// A new locale identifier with the all the empty subtags filled in /// with a likely value. /// </summary> /// <returns> /// A new locale identifier with all subtags filled in. /// </returns> public LocaleIdentifier MostLikelySubtags() { var result = (LocaleIdentifier)this.MemberwiseClone(); // Remove the script code 'Zzzz' and the region code 'ZZ' if they occur. if (result.Script == "Zzzz") { result.Script = String.Empty; } if (result.Region == "ZZ") { result.Region = String.Empty; } // Short cut if all subtags have a value. if (result.Language != "" && result.Script != "" && result.Region != "") { return(result); } // Find the language in likely subtags. var likely = new[] { $"{result.Language}_{result.Script}_{result.Region}", $"{result.Language}_{result.Region}", $"{result.Language}_{result.Script}", $"{result.Language}", $"und_{result.Script}", } .Select(k => k.Replace("__", "_").Trim('_')) .Where(k => k != String.Empty) .Distinct() .Select(k => Cldr.Instance .GetDocuments("common/supplemental/likelySubtags.xml") .FirstElementOrDefault($"supplementalData/likelySubtags/likelySubtag[@from='{k}']") ) .FirstOrDefault(e => e != null); if (likely != null) { var defaults = LocaleIdentifier.ParseBcp47(likely.GetAttribute("to", "")); if (result.Language == "") { result.Language = defaults.Language; } if (result.Script == "") { result.Script = defaults.Script; } if (result.Region == "") { result.Region = defaults.Region; } } return(result); }
public void Parsing_Language_Region() { var id = LocaleIdentifier.Parse("es-419"); Assert.AreEqual("es", id.Language); Assert.AreEqual("419", id.Region); Assert.IsFalse(LocaleIdentifier.TryParse("es-12345", out id)); }
public void Parsing_Invalid_Unicode_Extension() { LocaleIdentifier id; string message; var ok = LocaleIdentifier.TryParse("th-u-xx-invalidtype", out id, out message); Assert.IsFalse(ok); Assert.IsNull(id); }
public void Parsing_Language_Script() { var id = LocaleIdentifier.Parse("uz-Cyrl"); Assert.AreEqual("uz", id.Language); Assert.AreEqual("Cyrl", id.Script); Assert.IsFalse(LocaleIdentifier.TryParse("es-NotScript", out id)); }
public void Parsing_Language_Country() { var id = LocaleIdentifier.Parse("en-US"); Assert.AreEqual("en", id.Language); Assert.AreEqual("US", id.Region); Assert.IsFalse(LocaleIdentifier.TryParse("en-NotACountryCode", out id)); }
public void Parsing_Script_Region() { var id = LocaleIdentifier.Parse("Cyrl-RU"); Assert.AreEqual("Cyrl", id.Script); Assert.AreEqual("RU", id.Region); Assert.IsFalse(LocaleIdentifier.TryParse("Cyrl-NotACounty", out id)); }
/// <summary> /// Creates or reuses a locale with the specified <see cref="LocaleIdentifier"/>. /// </summary> /// <param name="id"> /// A locale identifier. /// </param> /// <returns> /// A locale for the specified <paramref name="id"/>. /// </returns> /// <remarks> /// Uses the <see cref="LocaleIdentifier.CanonicalForm"/> of the /// <paramref name="id"/>. /// </remarks> public static Locale Create(LocaleIdentifier id) { var cid = id.CanonicalForm(); if (log.IsDebugEnabled) { log.DebugFormat("Resolved locale '{0}' to '{1}'", id, cid); } return(LocaleCache.GetOrAdd(cid.ToString(), name => new Locale(cid))); }
public void Parsing_Language_Script_Country() { var id = LocaleIdentifier.Parse("zh-Hant-CN"); Assert.AreEqual("zh", id.Language); Assert.AreEqual("Hant", id.Script); Assert.AreEqual("CN", id.Region); Assert.IsFalse(LocaleIdentifier.TryParse("zh-Hant-NotACountry", out id)); }
public void Parsing_Messages() { string message; LocaleIdentifier id; var ok = LocaleIdentifier.TryParse("en-r-alpha-r-alpha", out id, out message); Assert.AreEqual(false, ok); Assert.AreEqual(null, id); Assert.AreEqual("'en-r-alpha-r-alpha' is not a valid locale identifier because an extension is duplicated.", message); }
public void SearchChain_Unicode_Variant_Extension() { var id = LocaleIdentifier.Parse("en-u-va-posix"); var chain = id.SearchChain().ToArray(); Assert.AreEqual(3, chain.Length); Assert.AreEqual("en_POSIX", chain[0]); Assert.AreEqual("en", chain[1]); Assert.AreEqual("root", chain[2]); }
public void Parsing_Extension() { var id = LocaleIdentifier.Parse("en-Latn-GB-r-extended-sequence-r-foo"); Assert.AreEqual("en", id.Language); Assert.AreEqual("Latn", id.Script); Assert.AreEqual("GB", id.Region); Assert.IsTrue(id.Extensions.Contains("r-extended-sequence")); Assert.IsTrue(id.Extensions.Contains("r-foo")); }
/// <summary> /// Tries parsing the string representation of a locale identifier. /// </summary> /// <param name="s"> /// A case insensitive string containing a locale identifier, based on BCP47. /// </param> /// <param name="result"> /// A BCP 47 language identifier that refers to <paramref name="s"/> or <b>null</b> if the parsing /// failed. /// </param> /// <param name="message"> /// The reason why the parsing failed. /// </param> /// <returns> /// <b>true</b> if <paramref name="s"/> was parsed successfully; otherwise, <b>false</b>. /// </returns> /// <remarks> /// The transformation rules for converting a BCP 47 tag into a /// Unicode Locale ID are <b>not</b> applied. /// </remarks> public static bool TryParseBcp47(string s, out LocaleIdentifier result, out string message) { result = null; message = null; var match = idRegex.Match(s.ToLowerInvariant()); if (!match.Success) { message = $"'{s}' is not a valid locale identifier."; return(false); } // Variants cannot be repeated. var variants = match.Groups["variants"] .Value.Split('-', '_') .Where(sv => !string.IsNullOrEmpty(sv)) .ToArray(); if (variants.Distinct().Count() != variants.Length) { message = $"'{s}' is not a valid locale identifier because a variant is duplicated."; return(false); } // Extensions cannot be repeated. var extensions = new List <string>(); foreach (Capture capture in match.Groups["ext"].Captures) { extensions.Add(capture.Value.Replace('_', '-')); } if (extensions.Distinct().Count() != extensions.Count) { message = $"'{s}' is not a valid locale identifier because an extension is duplicated."; return(false); } var u = extensions .Where(x => x.StartsWith("u-")) .Select(x => LocaleExtension.Parse(x)) .FirstOrDefault(); result = new LocaleIdentifier { Language = match.Groups["lang"].Value, Script = ToTitleCase(match.Groups["script"].Value), Region = match.Groups["region"].Value.ToUpperInvariant(), Variants = variants, Extensions = extensions.ToArray(), UnicodeExtension = u ?? LocaleExtension.Empty }; return(true); }
public void Parsing_Unicode_Extension() { var id = LocaleIdentifier.Parse("th-u-bar-foo-ca-buddhist-kk-nu-thai"); var extension = id.UnicodeExtension; CollectionAssert.Contains(extension.Attributes.ToArray(), "foo"); CollectionAssert.Contains(extension.Attributes.ToArray(), "bar"); Assert.AreEqual("buddhist", extension.Keywords["ca"]); Assert.AreEqual("true", extension.Keywords["kk"]); Assert.AreEqual("thai", extension.Keywords["nu"]); }
public void Parsing_Variants_Are_Not_Repeated() { string message; LocaleIdentifier id; var ok = LocaleIdentifier.TryParse("de-CH-1901-1901", out id, out message); Assert.AreEqual(false, ok); Assert.AreEqual(null, id); Assert.AreEqual("'de-CH-1901-1901' is not a valid locale identifier because a variant is duplicated.", message); ExceptionAssert.Throws <FormatException>(() => LocaleIdentifier.Parse("de-CH-1901-1901")); }
public void Parsing_Transforms() { Assert.AreEqual("en-US", LocaleIdentifier.Parse("en-US").ToString()); Assert.AreEqual("root", LocaleIdentifier.Parse("und").ToString()); Assert.AreEqual("und-US", LocaleIdentifier.Parse("und-US").ToString()); Assert.AreEqual("root-u-cu-usd", LocaleIdentifier.Parse("und-u-cu-USD").ToString()); Assert.AreEqual("zh-TW", LocaleIdentifier.Parse("cmn-TW").ToString()); Assert.AreEqual("sr-RS", LocaleIdentifier.Parse("sr-CS").ToString()); Assert.AreEqual("sr-Latn", LocaleIdentifier.Parse("sh").ToString()); Assert.AreEqual("sr-Cyrl", LocaleIdentifier.Parse("sh-Cyrl").ToString()); Assert.AreEqual("hy-AM", LocaleIdentifier.Parse("hy-SU").ToString()); }
public void Formatting() { var id = LocaleIdentifier.Parse("EN_LATN_GB_R_EXTENDED_SEQUENCE_R-FOO"); Assert.AreEqual("en-Latn-GB-r-extended-sequence-r-foo", id.ToString()); id = LocaleIdentifier.Parse("EN_nz"); Assert.AreEqual("en-NZ", id.ToString()); id = LocaleIdentifier.Parse("EN"); Assert.AreEqual("en", id.ToString()); }
public void Empty_Tags() { var id = LocaleIdentifier.Parse("Cyrl"); Assert.AreEqual("", id.Language); Assert.AreEqual("Cyrl", id.Script); Assert.AreEqual("", id.Region); Assert.AreEqual(0, id.Extensions.Count()); Assert.AreEqual(0, id.Variants.Count()); id = LocaleIdentifier.Parse("en"); Assert.AreEqual("en", id.Language); Assert.AreEqual("", id.Script); Assert.AreEqual("", id.Region); Assert.AreEqual(0, id.Extensions.Count()); Assert.AreEqual(0, id.Variants.Count()); }
static IEnumerable <string> SearchChainRecursive(LocaleIdentifier id) { foreach (var locale in id.SearchChain()) { yield return(locale); if (ParentLocales.Value.ContainsKey(locale)) { var parent = LocaleIdentifier.Parse(ParentLocales.Value[locale]); foreach (var p in SearchChainRecursive(parent)) { yield return(p); } yield break; } } }
/// <summary> /// A new locale idenyifer with empty subtags that <see cref="MostLikelySubtags"/> would fill. /// </summary> /// <returns> /// A new locale identifier. /// </returns> public LocaleIdentifier RemoveMostLikelySubtags() { var max = this.MostLikelySubtags(); max.Variants = new string[0]; var trials = new[] { max.Language, $"{max.Language}-{max.Region}", $"{max.Language}-{max.Script}" }; foreach (var trial in trials) { var id = LocaleIdentifier.ParseBcp47(trial); if (max.ToUnicodeLanguage() == id.MostLikelySubtags().ToUnicodeLanguage()) { id.Variants = this.Variants; return(id); } } max.Variants = this.Variants; return(max); }
public void UnicodeLangugeTag() { var id = LocaleIdentifier.Parse("EN_LATN_GB_R_EXTENDED_SEQUENCE_R-FOO"); Assert.AreEqual("en_Latn_GB", id.ToUnicodeLanguage()); id = LocaleIdentifier.Parse("EN_nz"); Assert.AreEqual("en_NZ", id.ToUnicodeLanguage()); id = LocaleIdentifier.Parse("EN"); Assert.AreEqual("en", id.ToUnicodeLanguage()); id = LocaleIdentifier.Parse("DE-ch-1996"); Assert.AreEqual("de_CH_1996", id.ToUnicodeLanguage()); id = LocaleIdentifier.Parse("sl-nedis"); Assert.AreEqual("sl_nedis", id.ToUnicodeLanguage()); id = LocaleIdentifier.Parse("sl-nedis"); Assert.AreEqual("sl_NEDIS", id.ToUnicodeLanguage(true)); }
public void SearchChain() { var id = LocaleIdentifier.Parse("sl-SI-nedis"); var chain = id.SearchChain().ToArray(); Assert.AreEqual(5, chain.Length); Assert.AreEqual("sl_SI_NEDIS", chain[0]); Assert.AreEqual("sl_NEDIS", chain[1]); Assert.AreEqual("sl_SI", chain[2]); Assert.AreEqual("sl", chain[3]); Assert.AreEqual("root", chain[4]); id = LocaleIdentifier.Parse("en-Latn-US-basiceng"); chain = id.SearchChain().ToArray(); Assert.AreEqual("en_Latn_US_BASICENG", chain[0]); Assert.AreEqual("en_US_BASICENG", chain[1]); Assert.AreEqual("en_Latn_BASICENG", chain[2]); Assert.AreEqual("en_BASICENG", chain[3]); Assert.AreEqual("en_Latn_US", chain[4]); Assert.AreEqual("en_US", chain[5]); Assert.AreEqual("en_Latn", chain[6]); Assert.AreEqual("en", chain[7]); Assert.AreEqual("root", chain[8]); }