mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Backed out changeset 804f26b2c6b8 (bug 1428698) for xpcshell failure on toolkit/mozapps/extensions/test/xpcshell/test_bug397778.js on a CLOSED TREE
--HG-- extra : amend_source : 0a86497ef3fed6c36a638ccc640d1eccbe14bce6
This commit is contained in:
parent
49993bfe85
commit
f0dfa23b9e
@ -446,7 +446,7 @@ LocaleService::FilterMatches(const nsTArray<nsCString>& aRequested,
|
||||
// aRetVal, so that no available locale will be found more than once.
|
||||
AutoTArray<Locale, 100> availLocales;
|
||||
for (auto& avail : aAvailable) {
|
||||
availLocales.AppendElement(Locale(avail));
|
||||
availLocales.AppendElement(Locale(avail, true));
|
||||
}
|
||||
|
||||
// Helper to erase an entry from availLocales once we have copied it to
|
||||
@ -460,12 +460,9 @@ LocaleService::FilterMatches(const nsTArray<nsCString>& aRequested,
|
||||
};
|
||||
|
||||
for (auto& requested : aRequested) {
|
||||
if (requested.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 1) Try to find a simple (case-insensitive) string match for the request.
|
||||
auto matchesExactly = [&](Locale& aLoc) {
|
||||
auto matchesExactly = [&](const Locale& aLoc) {
|
||||
return requested.Equals(aLoc.AsString(),
|
||||
nsCaseInsensitiveCStringComparator());
|
||||
};
|
||||
@ -481,9 +478,9 @@ LocaleService::FilterMatches(const nsTArray<nsCString>& aRequested,
|
||||
}
|
||||
|
||||
// 2) Try to match against the available locales treated as ranges.
|
||||
auto findRangeMatches = [&](Locale& aReq, bool aAvailRange, bool aReqRange) {
|
||||
auto matchesRange = [&](Locale& aLoc) {
|
||||
return aLoc.Matches(aReq, aAvailRange, aReqRange);
|
||||
auto findRangeMatches = [&](const Locale& aReq) {
|
||||
auto matchesRange = [&](const Locale& aLoc) {
|
||||
return aReq.Matches(aLoc);
|
||||
};
|
||||
bool foundMatch = false;
|
||||
auto match = availLocales.begin();
|
||||
@ -499,35 +496,35 @@ LocaleService::FilterMatches(const nsTArray<nsCString>& aRequested,
|
||||
return foundMatch;
|
||||
};
|
||||
|
||||
Locale requestedLocale = Locale(requested);
|
||||
if (findRangeMatches(requestedLocale, true, false)) {
|
||||
Locale requestedLocale = Locale(requested, false);
|
||||
if (findRangeMatches(requestedLocale)) {
|
||||
HANDLE_STRATEGY;
|
||||
}
|
||||
|
||||
// 3) Try to match against a maximized version of the requested locale
|
||||
if (requestedLocale.AddLikelySubtags()) {
|
||||
if (findRangeMatches(requestedLocale, true, false)) {
|
||||
if (findRangeMatches(requestedLocale)) {
|
||||
HANDLE_STRATEGY;
|
||||
}
|
||||
}
|
||||
|
||||
// 4) Try to match against a variant as a range
|
||||
requestedLocale.ClearVariants();
|
||||
if (findRangeMatches(requestedLocale, true, true)) {
|
||||
requestedLocale.SetVariantRange();
|
||||
if (findRangeMatches(requestedLocale)) {
|
||||
HANDLE_STRATEGY;
|
||||
}
|
||||
|
||||
// 5) Try to match against the likely subtag without region
|
||||
requestedLocale.ClearRegion();
|
||||
if (requestedLocale.AddLikelySubtags()) {
|
||||
if (findRangeMatches(requestedLocale, true, false)) {
|
||||
if (requestedLocale.AddLikelySubtagsWithoutRegion()) {
|
||||
if (findRangeMatches(requestedLocale)) {
|
||||
HANDLE_STRATEGY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 6) Try to match against a region as a range
|
||||
requestedLocale.ClearRegion();
|
||||
if (findRangeMatches(requestedLocale, true, true)) {
|
||||
requestedLocale.SetRegionRange();
|
||||
if (findRangeMatches(requestedLocale)) {
|
||||
HANDLE_STRATEGY;
|
||||
}
|
||||
}
|
||||
@ -595,12 +592,10 @@ LocaleService::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
}
|
||||
|
||||
bool
|
||||
LocaleService::LanguagesMatch(const nsACString& aRequested,
|
||||
const nsACString& aAvailable)
|
||||
LocaleService::LanguagesMatch(const nsCString& aRequested,
|
||||
const nsCString& aAvailable)
|
||||
{
|
||||
Locale requested = Locale(aRequested);
|
||||
Locale available = Locale(aAvailable);
|
||||
return requested.GetLanguage().Equals(available.GetLanguage());
|
||||
return Locale(aRequested, true).LanguageMatches(Locale(aAvailable, true));
|
||||
}
|
||||
|
||||
|
||||
|
@ -247,8 +247,8 @@ public:
|
||||
*/
|
||||
bool IsAppLocaleRTL();
|
||||
|
||||
static bool LanguagesMatch(const nsACString& aRequested,
|
||||
const nsACString& aAvailable);
|
||||
static bool LanguagesMatch(const nsCString& aRequested,
|
||||
const nsCString& aAvailable);
|
||||
|
||||
bool IsServer();
|
||||
|
||||
|
@ -5,9 +5,6 @@
|
||||
|
||||
#include "mozilla/intl/MozLocale.h"
|
||||
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
|
||||
#include "unicode/uloc.h"
|
||||
|
||||
using namespace mozilla::intl;
|
||||
@ -16,174 +13,134 @@ using namespace mozilla::intl;
|
||||
* Note: The file name is `MozLocale` to avoid compilation problems on case-insensitive
|
||||
* Windows. The class name is `Locale`.
|
||||
*/
|
||||
Locale::Locale(const nsACString& aLocale)
|
||||
Locale::Locale(const nsCString& aLocale, bool aRange)
|
||||
: mLocaleStr(aLocale)
|
||||
{
|
||||
int32_t position = 0;
|
||||
|
||||
if (!IsASCII(aLocale)) {
|
||||
mIsValid = false;
|
||||
return;
|
||||
}
|
||||
int32_t partNum = 0;
|
||||
|
||||
nsAutoCString normLocale(aLocale);
|
||||
normLocale.ReplaceChar('_', '-');
|
||||
|
||||
/**
|
||||
* BCP47 language tag:
|
||||
*
|
||||
* langtag = language 2*3ALPHA
|
||||
* ["-" extlang] 3ALPHA *2("-" 3ALPHA)
|
||||
* ["-" script] 4ALPHA
|
||||
* ["-" region] 2ALPHA / 3DIGIT
|
||||
* *("-" variant) 5*8alphanum / (DIGIT 3alphanum)
|
||||
* *("-" extension) [0-9a-wy-z] 1*("-" (1*8alphanum))
|
||||
* ["-" privateuse] x 1*("-" (1*8alphanum))
|
||||
*
|
||||
* This class currently supports a subset of the full BCP47 language tag
|
||||
* with a single extension of allowing variants to be 3ALPHA to support
|
||||
* `ja-JP-mac` code:
|
||||
*
|
||||
* langtag = language 2*3ALPHA
|
||||
* ["-" script] 4ALPHA
|
||||
* ["-" region] 2ALPHA
|
||||
* *("-" variant) 3*8alphanum
|
||||
*
|
||||
* The `position` variable represents the currently expected section of the tag
|
||||
* and intentionally skips positions (like `extlang`) which may be added later.
|
||||
*/
|
||||
for (const nsACString& subTag : normLocale.Split('-')) {
|
||||
auto slen = subTag.Length();
|
||||
if (position == 0) {
|
||||
if (slen < 2 || slen > 3) {
|
||||
mIsValid = false;
|
||||
return;
|
||||
}
|
||||
mLanguage = subTag;
|
||||
ToLowerCase(mLanguage);
|
||||
position = 2;
|
||||
} else if (position <= 2 && slen == 4) {
|
||||
mScript = subTag;
|
||||
ToLowerCase(mScript);
|
||||
mScript.Replace(0, 1, ToUpperCase(mScript[0]));
|
||||
position = 3;
|
||||
} else if (position <= 3 && slen == 2) {
|
||||
mRegion = subTag;
|
||||
ToUpperCase(mRegion);
|
||||
position = 4;
|
||||
} else if (position <= 4 && slen >= 3 && slen <= 8) {
|
||||
// we're quirky here because we allow for variant to be 3 char long.
|
||||
// BCP47 requires variants to be 5-8 char long at lest.
|
||||
//
|
||||
// We do this to support the `ja-JP-mac` quirk that we have.
|
||||
nsAutoCString lcSubTag(subTag);
|
||||
ToLowerCase(lcSubTag);
|
||||
mVariants.InsertElementSorted(lcSubTag);
|
||||
position = 4;
|
||||
for (const nsACString& part : normLocale.Split('-')) {
|
||||
switch (partNum) {
|
||||
case 0:
|
||||
if (part.EqualsLiteral("*") ||
|
||||
part.Length() == 2 || part.Length() == 3) {
|
||||
mLanguage.Assign(part);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (part.EqualsLiteral("*") || part.Length() == 4) {
|
||||
mScript.Assign(part);
|
||||
break;
|
||||
}
|
||||
|
||||
// fallover to region case
|
||||
partNum++;
|
||||
MOZ_FALLTHROUGH;
|
||||
case 2:
|
||||
if (part.EqualsLiteral("*") || part.Length() == 2) {
|
||||
mRegion.Assign(part);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (part.EqualsLiteral("*") || (part.Length() >= 3 && part.Length() <= 8)) {
|
||||
mVariant.Assign(part);
|
||||
}
|
||||
break;
|
||||
}
|
||||
partNum++;
|
||||
}
|
||||
|
||||
if (aRange) {
|
||||
if (mLanguage.IsEmpty()) {
|
||||
mLanguage.AssignLiteral("*");
|
||||
}
|
||||
if (mScript.IsEmpty()) {
|
||||
mScript.AssignLiteral("*");
|
||||
}
|
||||
if (mRegion.IsEmpty()) {
|
||||
mRegion.AssignLiteral("*");
|
||||
}
|
||||
if (mVariant.IsEmpty()) {
|
||||
mVariant.AssignLiteral("*");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Locale::IsValid()
|
||||
static bool
|
||||
SubtagMatches(const nsCString& aSubtag1, const nsCString& aSubtag2)
|
||||
{
|
||||
return mIsValid;
|
||||
}
|
||||
|
||||
const nsCString
|
||||
Locale::AsString()
|
||||
{
|
||||
nsCString tag;
|
||||
|
||||
if (!mIsValid) {
|
||||
tag.AppendLiteral("und");
|
||||
return tag;
|
||||
}
|
||||
|
||||
tag.Append(mLanguage);
|
||||
|
||||
if (!mScript.IsEmpty()) {
|
||||
tag.AppendLiteral("-");
|
||||
tag.Append(mScript);
|
||||
}
|
||||
|
||||
if (!mRegion.IsEmpty()) {
|
||||
tag.AppendLiteral("-");
|
||||
tag.Append(mRegion);
|
||||
}
|
||||
|
||||
for (const auto& variant : mVariants) {
|
||||
tag.AppendLiteral("-");
|
||||
tag.Append(variant);
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
const nsACString&
|
||||
Locale::GetLanguage() const
|
||||
{
|
||||
return mLanguage;
|
||||
}
|
||||
|
||||
const nsACString&
|
||||
Locale::GetScript() const
|
||||
{
|
||||
return mScript;
|
||||
}
|
||||
|
||||
const nsACString&
|
||||
Locale::GetRegion() const
|
||||
{
|
||||
return mRegion;
|
||||
}
|
||||
|
||||
const nsTArray<nsCString>&
|
||||
Locale::GetVariants() const
|
||||
{
|
||||
return mVariants;
|
||||
return aSubtag1.EqualsLiteral("*") ||
|
||||
aSubtag2.EqualsLiteral("*") ||
|
||||
aSubtag1.Equals(aSubtag2, nsCaseInsensitiveCStringComparator());
|
||||
}
|
||||
|
||||
bool
|
||||
Locale::Matches(const Locale& aOther, bool aThisRange, bool aOtherRange) const
|
||||
Locale::Matches(const Locale& aLocale) const
|
||||
{
|
||||
if ((!aThisRange || !mLanguage.IsEmpty()) &&
|
||||
(!aOtherRange || !aOther.mLanguage.IsEmpty()) &&
|
||||
!mLanguage.Equals(aOther.mLanguage)) {
|
||||
return false;
|
||||
}
|
||||
return SubtagMatches(mLanguage, aLocale.mLanguage) &&
|
||||
SubtagMatches(mScript, aLocale.mScript) &&
|
||||
SubtagMatches(mRegion, aLocale.mRegion) &&
|
||||
SubtagMatches(mVariant, aLocale.mVariant);
|
||||
}
|
||||
|
||||
if ((!aThisRange || !mScript.IsEmpty()) &&
|
||||
(!aOtherRange || !aOther.mScript.IsEmpty()) &&
|
||||
!mScript.Equals(aOther.mScript)) {
|
||||
return false;
|
||||
}
|
||||
if ((!aThisRange || !mRegion.IsEmpty()) &&
|
||||
(!aOtherRange || !aOther.mRegion.IsEmpty()) &&
|
||||
!mRegion.Equals(aOther.mRegion)) {
|
||||
return false;
|
||||
}
|
||||
if ((!aThisRange || !mVariants.IsEmpty()) &&
|
||||
(!aOtherRange || !aOther.mVariants.IsEmpty()) &&
|
||||
mVariants != aOther.mVariants) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
bool
|
||||
Locale::LanguageMatches(const Locale& aLocale) const
|
||||
{
|
||||
return SubtagMatches(mLanguage, aLocale.mLanguage) &&
|
||||
SubtagMatches(mScript, aLocale.mScript);
|
||||
}
|
||||
|
||||
void
|
||||
Locale::SetVariantRange()
|
||||
{
|
||||
mVariant.AssignLiteral("*");
|
||||
}
|
||||
|
||||
void
|
||||
Locale::SetRegionRange()
|
||||
{
|
||||
mRegion.AssignLiteral("*");
|
||||
}
|
||||
|
||||
bool
|
||||
Locale::AddLikelySubtags()
|
||||
{
|
||||
return AddLikelySubtagsForLocale(mLocaleStr);
|
||||
}
|
||||
|
||||
bool
|
||||
Locale::AddLikelySubtagsWithoutRegion()
|
||||
{
|
||||
nsAutoCString locale(mLanguage);
|
||||
|
||||
if (!mScript.IsEmpty()) {
|
||||
locale.Append("-");
|
||||
locale.Append(mScript);
|
||||
}
|
||||
|
||||
// We don't add variant here because likelySubtag doesn't care about it.
|
||||
|
||||
return AddLikelySubtagsForLocale(locale);
|
||||
}
|
||||
|
||||
bool
|
||||
Locale::AddLikelySubtagsForLocale(const nsACString& aLocale)
|
||||
{
|
||||
const int32_t kLocaleMax = 160;
|
||||
char maxLocale[kLocaleMax];
|
||||
nsAutoCString locale(aLocale);
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
uloc_addLikelySubtags(AsString().get(), maxLocale, kLocaleMax, &status);
|
||||
uloc_addLikelySubtags(locale.get(), maxLocale, kLocaleMax, &status);
|
||||
|
||||
if (U_FAILURE(status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsDependentCString maxLocStr(maxLocale);
|
||||
Locale loc = Locale(maxLocStr);
|
||||
Locale loc = Locale(maxLocStr, false);
|
||||
|
||||
if (loc == *this) {
|
||||
return false;
|
||||
@ -198,15 +155,3 @@ Locale::AddLikelySubtags()
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Locale::ClearVariants()
|
||||
{
|
||||
mVariants.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
Locale::ClearRegion()
|
||||
{
|
||||
mRegion.Truncate();
|
||||
}
|
||||
|
@ -3,91 +3,62 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_intl_MozLocale_h__
|
||||
#define mozilla_intl_MozLocale_h__
|
||||
#ifndef mozilla_intl_Locale_h__
|
||||
#define mozilla_intl_Locale_h__
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace intl {
|
||||
|
||||
/**
|
||||
* Locale class is a core representation of a single locale.
|
||||
*
|
||||
* A locale is a data object representing a combination of language, script,
|
||||
* region, variant and a set of regional extension preferences that may further specify
|
||||
* particular user choices like calendar, numbering system, etc.
|
||||
*
|
||||
* A locale can be expressed as a language tag string, like a simple "fr" for French,
|
||||
* or a more specific "sr-Cyrl-RS-u-hc-h12" for Serbian in Russia with a Cyrylic script,
|
||||
* and hour cycle selected to be `h12`.
|
||||
*
|
||||
* The format of the language tag follows BCP47 standard and implements a subset of it.
|
||||
* In the future we expect to extend this class to cover more subtags and extensions.
|
||||
*
|
||||
* BCP47: https://tools.ietf.org/html/bcp47
|
||||
*
|
||||
* The aim of this class it aid in validation, parsing and canonicalization of the
|
||||
* string.
|
||||
*
|
||||
* It allows the user to input any well-formed BCP47 language tag and operate
|
||||
* on its subtags in a canonicalized form.
|
||||
*
|
||||
* It should be used for all operations on language tags, and together with
|
||||
* LocaleService::NegotiateLanguages for language negotiation.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Locale loc = Locale("de-at");
|
||||
*
|
||||
* ASSERT_TRUE(loc.GetLanguage().Equals("de"));
|
||||
* ASSERT_TRUE(loc.GetScript().IsEmpty());
|
||||
* ASSERT_TRUE(loc.GetRegion().Equals("AT")); // canonicalized to upper case
|
||||
* Locale object, a BCP47-style tag decomposed into subtags for
|
||||
* matching purposes.
|
||||
*
|
||||
* If constructed with aRange = true, any missing subtags will be
|
||||
* set to "*".
|
||||
*
|
||||
* Note: The file name is `MozLocale` to avoid compilation problems on case-insensitive
|
||||
* Windows. The class name is `Locale`.
|
||||
*/
|
||||
class Locale {
|
||||
public:
|
||||
explicit Locale(const nsACString& aLocale);
|
||||
explicit Locale(const char* aLocale)
|
||||
: Locale(nsDependentCString(aLocale))
|
||||
{ };
|
||||
Locale(const nsCString& aLocale, bool aRange);
|
||||
|
||||
const nsACString& GetLanguage() const;
|
||||
const nsACString& GetScript() const;
|
||||
const nsACString& GetRegion() const;
|
||||
const nsTArray<nsCString>& GetVariants() const;
|
||||
bool Matches(const Locale& aLocale) const;
|
||||
bool LanguageMatches(const Locale& aLocale) const;
|
||||
|
||||
bool IsValid();
|
||||
const nsCString AsString();
|
||||
|
||||
bool Matches(const Locale& aOther, bool aThisRange, bool aOtherRange) const;
|
||||
void SetVariantRange();
|
||||
void SetRegionRange();
|
||||
|
||||
// returns false if nothing changed
|
||||
bool AddLikelySubtags();
|
||||
void ClearVariants();
|
||||
void ClearRegion();
|
||||
bool AddLikelySubtagsWithoutRegion();
|
||||
|
||||
const nsCString& AsString() const {
|
||||
return mLocaleStr;
|
||||
}
|
||||
|
||||
bool operator== (const Locale& aOther) {
|
||||
return mLanguage.Equals(aOther.mLanguage) &&
|
||||
mScript.Equals(aOther.mScript) &&
|
||||
mRegion.Equals(aOther.mRegion) &&
|
||||
mVariants == aOther.mVariants;
|
||||
|
||||
const auto& cmp = nsCaseInsensitiveCStringComparator();
|
||||
return mLanguage.Equals(aOther.mLanguage, cmp) &&
|
||||
mScript.Equals(aOther.mScript, cmp) &&
|
||||
mRegion.Equals(aOther.mRegion, cmp) &&
|
||||
mVariant.Equals(aOther.mVariant, cmp);
|
||||
}
|
||||
|
||||
private:
|
||||
nsAutoCStringN<3> mLanguage;
|
||||
nsAutoCStringN<4> mScript;
|
||||
nsAutoCStringN<2> mRegion;
|
||||
nsTArray<nsCString> mVariants;
|
||||
bool mIsValid = true;
|
||||
const nsCString& mLocaleStr;
|
||||
nsCString mLanguage;
|
||||
nsCString mScript;
|
||||
nsCString mRegion;
|
||||
nsCString mVariant;
|
||||
|
||||
bool AddLikelySubtagsForLocale(const nsACString& aLocale);
|
||||
};
|
||||
|
||||
} // intl
|
||||
} // namespace mozilla
|
||||
|
||||
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::intl::Locale)
|
||||
|
||||
#endif /* mozilla_intl_MozLocale_h__ */
|
||||
#endif /* mozilla_intl_Locale_h__ */
|
||||
|
@ -1,64 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "mozilla/intl/MozLocale.h"
|
||||
|
||||
using namespace mozilla::intl;
|
||||
|
||||
|
||||
TEST(Intl_Locale_Locale, Locale) {
|
||||
Locale loc = Locale("en-US");
|
||||
|
||||
ASSERT_TRUE(loc.GetLanguage().Equals("en"));
|
||||
ASSERT_TRUE(loc.GetRegion().Equals("US"));
|
||||
}
|
||||
|
||||
TEST(Intl_Locale_Locale, AsString) {
|
||||
Locale loc = Locale("ja-jp-windows");
|
||||
|
||||
ASSERT_TRUE(loc.AsString().Equals("ja-JP-windows"));
|
||||
}
|
||||
|
||||
TEST(Intl_Locale_Locale, GetSubTags) {
|
||||
Locale loc = Locale("en-latn-us-macos");
|
||||
|
||||
ASSERT_TRUE(loc.GetLanguage().Equals("en"));
|
||||
ASSERT_TRUE(loc.GetScript().Equals("Latn"));
|
||||
ASSERT_TRUE(loc.GetRegion().Equals("US"));
|
||||
ASSERT_TRUE(loc.GetVariants().Length() == 1);
|
||||
ASSERT_TRUE(loc.GetVariants()[0].Equals("macos"));
|
||||
}
|
||||
|
||||
TEST(Intl_Locale_Locale, Matches) {
|
||||
Locale loc = Locale("en-US");
|
||||
|
||||
Locale loc2 = Locale("en-GB");
|
||||
ASSERT_FALSE(loc == loc2);
|
||||
|
||||
Locale loc3 = Locale("en-US");
|
||||
ASSERT_TRUE(loc == loc3);
|
||||
|
||||
Locale loc4 = Locale("En_us");
|
||||
ASSERT_TRUE(loc == loc4);
|
||||
}
|
||||
|
||||
TEST(Intl_Locale_Locale, MatchesRange) {
|
||||
Locale loc = Locale("en-US");
|
||||
|
||||
Locale loc2 = Locale("en-Latn-US");
|
||||
ASSERT_FALSE(loc == loc2);
|
||||
ASSERT_TRUE(loc.Matches(loc2, true, false));
|
||||
ASSERT_FALSE(loc.Matches(loc2, false, true));
|
||||
ASSERT_FALSE(loc.Matches(loc2, false, false));
|
||||
ASSERT_TRUE(loc.Matches(loc2, true, true));
|
||||
|
||||
Locale loc3 = Locale("en");
|
||||
ASSERT_FALSE(loc == loc3);
|
||||
ASSERT_TRUE(loc.Matches(loc3, false, true));
|
||||
ASSERT_FALSE(loc.Matches(loc3, true, false));
|
||||
ASSERT_FALSE(loc.Matches(loc3, false, false));
|
||||
ASSERT_TRUE(loc.Matches(loc3, true, true));
|
||||
}
|
@ -9,7 +9,6 @@ UNIFIED_SOURCES += [
|
||||
'TestDateTimeFormat.cpp',
|
||||
'TestLocaleService.cpp',
|
||||
'TestLocaleServiceNegotiate.cpp',
|
||||
'TestMozLocale.cpp',
|
||||
'TestOSPreferences.cpp',
|
||||
]
|
||||
|
||||
|
@ -12,16 +12,16 @@ const data = {
|
||||
[["en"], ["en"], ["en"]],
|
||||
[["en-US"], ["en-US"], ["en-US"]],
|
||||
[["en-Latn-US"], ["en-Latn-US"], ["en-Latn-US"]],
|
||||
[["en-Latn-US-windows"], ["en-Latn-US-windows"], ["en-Latn-US-windows"]],
|
||||
[["en-Latn-US-mac"], ["en-Latn-US-mac"], ["en-Latn-US-mac"]],
|
||||
[["fr-FR"], ["de", "it", "fr-FR"], ["fr-FR"]],
|
||||
[["fr", "pl", "de-DE"], ["pl", "en-US", "de-DE"], ["pl", "de-DE"]],
|
||||
],
|
||||
"available as range": [
|
||||
[["en-US"], ["en"], ["en"]],
|
||||
[["en-Latn-US"], ["en-US"], ["en-US"]],
|
||||
[["en-US-windows"], ["en-US"], ["en-US"]],
|
||||
[["en-US-mac"], ["en-US"], ["en-US"]],
|
||||
[["fr-CA", "de-DE"], ["fr", "it", "de"], ["fr", "de"]],
|
||||
[["ja-JP-windows"], ["ja"], ["ja"]],
|
||||
[["ja-JP-mac"], ["ja"], ["ja"]],
|
||||
[["en-Latn-GB", "en-Latn-IN"], ["en-IN", "en-GB"], ["en-GB", "en-IN"]],
|
||||
],
|
||||
"should match on likely subtag": [
|
||||
@ -38,27 +38,36 @@ const data = {
|
||||
"should match likelySubtag region over other regions": [
|
||||
[["en-CA"], ["en-ZA", "en-GB", "en-US"], ["en-US", "en-ZA", "en-GB"]],
|
||||
],
|
||||
"should match on a requested locale as a range": [
|
||||
[["en-*-US"], ["en-US"], ["en-US"]],
|
||||
[["en-Latn-US-*"], ["en-Latn-US"], ["en-Latn-US"]],
|
||||
[["en-*-US-*"], ["en-US"], ["en-US"]],
|
||||
],
|
||||
"should match cross-region": [
|
||||
[["en"], ["en-US"], ["en-US"]],
|
||||
[["en-US"], ["en-GB"], ["en-GB"]],
|
||||
[["en-Latn-US"], ["en-Latn-GB"], ["en-Latn-GB"]],
|
||||
// This is a cross-region check, because the requested Locale
|
||||
// is really lang: en, script: *, region: undefined
|
||||
[["en-*"], ["en-US"], ["en-US"]],
|
||||
],
|
||||
"should match cross-variant": [
|
||||
[["en-US-linux"], ["en-US-windows"], ["en-US-windows"]],
|
||||
[["en-US-mac"], ["en-US-win"], ["en-US-win"]],
|
||||
],
|
||||
"should prioritize properly": [
|
||||
// exact match first
|
||||
[["en-US"], ["en-US-windows", "en", "en-US"], ["en-US", "en", "en-US-windows"]],
|
||||
[["en-US"], ["en-US-mac", "en", "en-US"], ["en-US", "en", "en-US-mac"]],
|
||||
// available as range second
|
||||
[["en-Latn-US"], ["en-GB", "en-US"], ["en-US", "en-GB"]],
|
||||
// likely subtags third
|
||||
[["en"], ["en-Cyrl-US", "en-Latn-US"], ["en-Latn-US"]],
|
||||
// variant range fourth
|
||||
[["en-US-macos"], ["en-US-windows", "en-GB-macos"], ["en-US-windows", "en-GB-macos"]],
|
||||
[["en-US-mac"], ["en-US-win", "en-GB-mac"], ["en-US-win", "en-GB-mac"]],
|
||||
// regional range fifth
|
||||
[["en-US-macos"], ["en-GB-windows"], ["en-GB-windows"]],
|
||||
[["en-US-mac"], ["en-GB-win"], ["en-GB-win"]],
|
||||
],
|
||||
"should prioritize properly (extra tests)": [
|
||||
[["en-US"], ["en-GB", "en"], ["en", "en-GB"]],
|
||||
[["fr-CA-macos", "de-DE"], ["de-DE", "fr-FR-windows"], ["fr-FR-windows", "de-DE"]],
|
||||
],
|
||||
"should handle default locale properly": [
|
||||
[["fr"], ["de", "it"], []],
|
||||
@ -67,19 +76,16 @@ const data = {
|
||||
[["fr", "de-DE"], ["de-DE", "fr-CA"], "en-US", ["fr-CA", "de-DE", "en-US"]],
|
||||
],
|
||||
"should handle all matches on the 1st higher than any on the 2nd": [
|
||||
[["fr-CA-macos", "de-DE"], ["de-DE", "fr-FR-windows"], ["fr-FR-windows", "de-DE"]],
|
||||
[["fr-CA-mac", "de-DE"], ["de-DE", "fr-FR-win"], ["fr-FR-win", "de-DE"]],
|
||||
],
|
||||
"should handle cases and underscores": [
|
||||
[["fr_FR"], ["fr-FR"], ["fr-FR"]],
|
||||
[["fr_fr"], ["fr-fr"], ["fr-FR"]],
|
||||
[["fr_Fr"], ["fr-fR"], ["fr-FR"]],
|
||||
[["fr_fr"], ["fr-fr"], ["fr-fr"]],
|
||||
[["fr_Fr"], ["fr-fR"], ["fr-fR"]],
|
||||
[["fr_lAtN_fr"], ["fr-Latn-FR"], ["fr-Latn-FR"]],
|
||||
[["fr_FR"], ["fr_FR"], ["fr-FR"]],
|
||||
[["fr-FR"], ["fr_FR"], ["fr-FR"]],
|
||||
[["fr_Cyrl_FR_macos"], ["fr_Cyrl_fr-macos"], ["fr-Cyrl-FR-macos"]],
|
||||
],
|
||||
"should handle mozilla specific 3-letter variants": [
|
||||
[["ja-JP-mac", "de-DE"], ["ja-JP-mac", "de-DE"], ["ja-JP-mac", "de-DE"]],
|
||||
[["fr_FR"], ["fr_FR"], ["fr_FR"]],
|
||||
[["fr-FR"], ["fr_FR"], ["fr_FR"]],
|
||||
[["fr_Cyrl_FR_mac"], ["fr_Cyrl_fr-mac"], ["fr_Cyrl_fr-mac"]],
|
||||
],
|
||||
"should not crash on invalid input": [
|
||||
[null, ["fr-FR"], []],
|
||||
|
Loading…
Reference in New Issue
Block a user