[intl] Implement Intl Enumeration API
flag --harmony_intl_enumeration I2P: https://groups.google.com/a/chromium.org/g/blink-dev/c/Txtf_rSqGH8/m/e27FY33JAQAJ Design Doc: https://docs.google.com/document/d/1lbj_YVW-xhzYNMQeHB-qDjVkf4SA-eTHYpYXx3Oaud8 https://chromestatus.com/guide/edit/5649454590853120 Bug: v8:10743 Change-Id: I3bfe0c25b50eb55025498534eba975a20723bd2f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2953519 Commit-Queue: Frank Tang <ftang@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/master@{#76265}
This commit is contained in:
parent
4955ecfc68
commit
266bd5743f
@ -1053,6 +1053,8 @@ namespace internal {
|
||||
CPP(DisplayNamesSupportedLocalesOf) \
|
||||
/* ecma402 #sec-intl.getcanonicallocales */ \
|
||||
CPP(IntlGetCanonicalLocales) \
|
||||
/* ecma402 #sec-intl.supportedvaluesof */ \
|
||||
CPP(IntlSupportedValuesOf) \
|
||||
/* ecma402 #sec-intl-listformat-constructor */ \
|
||||
CPP(ListFormatConstructor) \
|
||||
/* ecma402 #sec-intl-list-format.prototype.format */ \
|
||||
|
@ -576,6 +576,13 @@ BUILTIN(IntlGetCanonicalLocales) {
|
||||
Intl::GetCanonicalLocales(isolate, locales));
|
||||
}
|
||||
|
||||
BUILTIN(IntlSupportedValuesOf) {
|
||||
HandleScope scope(isolate);
|
||||
Handle<Object> locales = args.atOrUndefined(isolate, 1);
|
||||
|
||||
RETURN_RESULT_OR_FAILURE(isolate, Intl::SupportedValuesOf(isolate, locales));
|
||||
}
|
||||
|
||||
BUILTIN(ListFormatConstructor) {
|
||||
HandleScope scope(isolate);
|
||||
|
||||
|
@ -293,7 +293,9 @@ DEFINE_BOOL(harmony_shipping, true, "enable all shipped harmony features")
|
||||
V(harmony_array_find_last, "harmony array find last helpers")
|
||||
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
#define HARMONY_INPROGRESS(V) HARMONY_INPROGRESS_BASE(V)
|
||||
#define HARMONY_INPROGRESS(V) \
|
||||
HARMONY_INPROGRESS_BASE(V) \
|
||||
V(harmony_intl_enumeration, "Intl Enumberation API")
|
||||
#else
|
||||
#define HARMONY_INPROGRESS(V) HARMONY_INPROGRESS_BASE(V)
|
||||
#endif
|
||||
|
@ -4594,6 +4594,20 @@ void Genesis::InitializeGlobal_harmony_intl_locale_info() {
|
||||
Builtin::kLocalePrototypeWeekInfo, true);
|
||||
}
|
||||
|
||||
void Genesis::InitializeGlobal_harmony_intl_enumeration() {
|
||||
if (!FLAG_harmony_intl_enumeration) return;
|
||||
|
||||
Handle<JSObject> intl = Handle<JSObject>::cast(
|
||||
JSReceiver::GetProperty(
|
||||
isolate(),
|
||||
Handle<JSReceiver>(native_context()->global_object(), isolate()),
|
||||
factory()->InternalizeUtf8String("Intl"))
|
||||
.ToHandleChecked());
|
||||
|
||||
SimpleInstallFunction(isolate(), intl, "supportedValuesOf",
|
||||
Builtin::kIntlSupportedValuesOf, 0, false);
|
||||
}
|
||||
|
||||
#endif // V8_INTL_SUPPORT
|
||||
|
||||
Handle<JSFunction> Genesis::CreateArrayBuffer(
|
||||
|
@ -1666,6 +1666,145 @@ MaybeHandle<JSArray> Intl::GetCanonicalLocales(Isolate* isolate,
|
||||
return CreateArrayFromList(isolate, maybe_ll.FromJust(), attr);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
MaybeHandle<JSArray> AvailableCollations(Isolate* isolate) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
std::unique_ptr<icu::StringEnumeration> enumeration(
|
||||
icu::Collator::getKeywordValues("collation", status));
|
||||
if (U_FAILURE(status)) {
|
||||
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError),
|
||||
JSArray);
|
||||
}
|
||||
return Intl::ToJSArray(isolate, "co", enumeration.get(),
|
||||
Intl::RemoveCollation, true);
|
||||
}
|
||||
|
||||
MaybeHandle<JSArray> VectorToJSArray(Isolate* isolate,
|
||||
const std::vector<std::string>& array) {
|
||||
Factory* factory = isolate->factory();
|
||||
Handle<FixedArray> fixed_array =
|
||||
factory->NewFixedArray(static_cast<int32_t>(array.size()));
|
||||
int32_t index = 0;
|
||||
for (std::string item : array) {
|
||||
Handle<String> str = factory->NewStringFromAsciiChecked(item.c_str());
|
||||
fixed_array->set(index++, *str);
|
||||
}
|
||||
return factory->NewJSArrayWithElements(fixed_array);
|
||||
}
|
||||
|
||||
MaybeHandle<JSArray> AvailableCurrencies(Isolate* isolate) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UEnumeration* ids =
|
||||
ucurr_openISOCurrencies(UCURR_COMMON | UCURR_NON_DEPRECATED, &status);
|
||||
const char* next = nullptr;
|
||||
std::vector<std::string> array;
|
||||
while (U_SUCCESS(status) &&
|
||||
(next = uenum_next(ids, nullptr, &status)) != nullptr) {
|
||||
array.push_back(next);
|
||||
}
|
||||
std::sort(array.begin(), array.end());
|
||||
uenum_close(ids);
|
||||
return VectorToJSArray(isolate, array);
|
||||
}
|
||||
|
||||
MaybeHandle<JSArray> AvailableNumberingSystems(Isolate* isolate) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
std::unique_ptr<icu::StringEnumeration> enumeration(
|
||||
icu::NumberingSystem::getAvailableNames(status));
|
||||
if (U_FAILURE(status)) {
|
||||
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError),
|
||||
JSArray);
|
||||
}
|
||||
// Need to filter out isAlgorithmic
|
||||
return Intl::ToJSArray(
|
||||
isolate, "nu", enumeration.get(),
|
||||
[](const char* value) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
std::unique_ptr<icu::NumberingSystem> numbering_system(
|
||||
icu::NumberingSystem::createInstanceByName(value, status));
|
||||
// Skip algorithmic one since chrome filter out the resource.
|
||||
return U_FAILURE(status) || numbering_system->isAlgorithmic();
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
MaybeHandle<JSArray> AvailableTimeZones(Isolate* isolate) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
std::unique_ptr<icu::StringEnumeration> enumeration(
|
||||
icu::TimeZone::createTimeZoneIDEnumeration(
|
||||
UCAL_ZONE_TYPE_CANONICAL_LOCATION, nullptr, nullptr, status));
|
||||
if (U_FAILURE(status)) {
|
||||
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError),
|
||||
JSArray);
|
||||
}
|
||||
return Intl::ToJSArray(isolate, nullptr, enumeration.get(), nullptr, true);
|
||||
}
|
||||
|
||||
MaybeHandle<JSArray> AvailableUnits(Isolate* isolate) {
|
||||
Factory* factory = isolate->factory();
|
||||
std::set<std::string> sanctioned(Intl::SanctionedSimpleUnits());
|
||||
Handle<FixedArray> fixed_array =
|
||||
factory->NewFixedArray(static_cast<int32_t>(sanctioned.size()));
|
||||
int32_t index = 0;
|
||||
for (std::string item : sanctioned) {
|
||||
Handle<String> str = factory->NewStringFromAsciiChecked(item.c_str());
|
||||
fixed_array->set(index++, *str);
|
||||
}
|
||||
return factory->NewJSArrayWithElements(fixed_array);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// ecma-402 #sec-intl.supportedvaluesof
|
||||
MaybeHandle<JSArray> Intl::SupportedValuesOf(Isolate* isolate,
|
||||
Handle<Object> key_obj) {
|
||||
Factory* factory = isolate->factory();
|
||||
// 1. 1. Let key be ? ToString(key).
|
||||
Handle<String> key_str;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(isolate, key_str,
|
||||
Object::ToString(isolate, key_obj), JSArray);
|
||||
// 2. If key is "calendar", then
|
||||
if (factory->calendar_string()->Equals(*key_str)) {
|
||||
// a. Let list be ! AvailableCalendars( ).
|
||||
return Intl::AvailableCalendars(isolate);
|
||||
}
|
||||
// 3. Else if key is "collation", then
|
||||
if (factory->collation_string()->Equals(*key_str)) {
|
||||
// a. Let list be ! AvailableCollations( ).
|
||||
return AvailableCollations(isolate);
|
||||
}
|
||||
// 4. Else if key is "currency", then
|
||||
if (factory->currency_string()->Equals(*key_str)) {
|
||||
// a. Let list be ! AvailableCurrencies( ).
|
||||
return AvailableCurrencies(isolate);
|
||||
}
|
||||
// 5. Else if key is "numberingSystem", then
|
||||
if (factory->numberingSystem_string()->Equals(*key_str)) {
|
||||
// a. Let list be ! AvailableNumberingSystems( ).
|
||||
return AvailableNumberingSystems(isolate);
|
||||
}
|
||||
// 6. Else if key is "timeZone", then
|
||||
if (factory->timeZone_string()->Equals(*key_str)) {
|
||||
// a. Let list be ! AvailableTimeZones( ).
|
||||
return AvailableTimeZones(isolate);
|
||||
}
|
||||
// 7. Else if key is "unit", then
|
||||
if (factory->unit_string()->Equals(*key_str)) {
|
||||
// a. Let list be ! AvailableUnits( ).
|
||||
return AvailableUnits(isolate);
|
||||
}
|
||||
// 8. Else,
|
||||
// a. Throw a RangeError exception.
|
||||
// 9. Return ! CreateArrayFromList( list ).
|
||||
|
||||
THROW_NEW_ERROR(
|
||||
isolate,
|
||||
NewRangeError(MessageTemplate::kInvalid,
|
||||
factory->NewStringFromStaticChars("key"), key_str),
|
||||
JSArray);
|
||||
}
|
||||
|
||||
// ECMA 402 Intl.*.supportedLocalesOf
|
||||
MaybeHandle<JSObject> Intl::SupportedLocalesOf(
|
||||
Isolate* isolate, const char* method,
|
||||
@ -2247,5 +2386,51 @@ MaybeHandle<JSReceiver> Intl::CoerceOptionsToObject(Isolate* isolate,
|
||||
return Handle<JSReceiver>::cast(options);
|
||||
}
|
||||
|
||||
MaybeHandle<JSArray> Intl::ToJSArray(
|
||||
Isolate* isolate, const char* unicode_key,
|
||||
icu::StringEnumeration* enumeration,
|
||||
const std::function<bool(const char*)>& removes, bool sort) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
std::vector<std::string> array;
|
||||
for (const char* item = enumeration->next(nullptr, status);
|
||||
U_SUCCESS(status) && item != nullptr;
|
||||
item = enumeration->next(nullptr, status)) {
|
||||
if (unicode_key != nullptr) {
|
||||
item = uloc_toUnicodeLocaleType(unicode_key, item);
|
||||
}
|
||||
if (removes == nullptr || !(removes)(item)) {
|
||||
array.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (sort) {
|
||||
std::sort(array.begin(), array.end());
|
||||
}
|
||||
return VectorToJSArray(isolate, array);
|
||||
}
|
||||
|
||||
bool Intl::RemoveCollation(const char* collation) {
|
||||
return strcmp("standard", collation) == 0 || strcmp("search", collation) == 0;
|
||||
}
|
||||
|
||||
// See the list in ecma402 #sec-issanctionedsimpleunitidentifier
|
||||
std::set<std::string> Intl::SanctionedSimpleUnits() {
|
||||
return std::set<std::string>({"acre", "bit", "byte",
|
||||
"celsius", "centimeter", "day",
|
||||
"degree", "fahrenheit", "fluid-ounce",
|
||||
"foot", "gallon", "gigabit",
|
||||
"gigabyte", "gram", "hectare",
|
||||
"hour", "inch", "kilobit",
|
||||
"kilobyte", "kilogram", "kilometer",
|
||||
"liter", "megabit", "megabyte",
|
||||
"meter", "mile", "mile-scandinavian",
|
||||
"millimeter", "milliliter", "millisecond",
|
||||
"minute", "month", "ounce",
|
||||
"percent", "petabyte", "pound",
|
||||
"second", "stone", "terabit",
|
||||
"terabyte", "week", "yard",
|
||||
"year"});
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -27,6 +27,7 @@ namespace U_ICU_NAMESPACE {
|
||||
class BreakIterator;
|
||||
class Collator;
|
||||
class FormattedValue;
|
||||
class StringEnumeration;
|
||||
class UnicodeString;
|
||||
} // namespace U_ICU_NAMESPACE
|
||||
|
||||
@ -142,6 +143,10 @@ class Intl {
|
||||
V8_WARN_UNUSED_RESULT static MaybeHandle<JSArray> GetCanonicalLocales(
|
||||
Isolate* isolate, Handle<Object> locales);
|
||||
|
||||
// ecma-402 #sec-intl.supportedvaluesof
|
||||
V8_WARN_UNUSED_RESULT static MaybeHandle<JSArray> SupportedValuesOf(
|
||||
Isolate* isolate, Handle<Object> key);
|
||||
|
||||
// For locale sensitive functions
|
||||
V8_WARN_UNUSED_RESULT static MaybeHandle<String> StringLocaleConvertCase(
|
||||
Isolate* isolate, Handle<String> s, bool is_upper,
|
||||
@ -338,6 +343,18 @@ class Intl {
|
||||
// ecma402/#sec-coerceoptionstoobject
|
||||
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> CoerceOptionsToObject(
|
||||
Isolate* isolate, Handle<Object> options, const char* service);
|
||||
|
||||
V8_WARN_UNUSED_RESULT static MaybeHandle<JSArray> ToJSArray(
|
||||
Isolate* isolate, const char* unicode_key,
|
||||
icu::StringEnumeration* enumeration,
|
||||
const std::function<bool(const char*)>& removes, bool sort);
|
||||
|
||||
static bool RemoveCollation(const char* collation);
|
||||
|
||||
static std::set<std::string> SanctionedSimpleUnits();
|
||||
|
||||
V8_WARN_UNUSED_RESULT static MaybeHandle<JSArray> AvailableCalendars(
|
||||
Isolate* isolate);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -481,57 +481,13 @@ MaybeHandle<JSLocale> JSLocale::Minimize(Isolate* isolate,
|
||||
return Construct(isolate, result);
|
||||
}
|
||||
|
||||
MaybeHandle<JSArray> ToJSArray(Isolate* isolate, const char* unicode_key,
|
||||
icu::StringEnumeration* enumeration,
|
||||
const std::set<std::string>& removes) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
Factory* factory = isolate->factory();
|
||||
|
||||
int32_t count = 0;
|
||||
if (!removes.empty()) {
|
||||
// If we may remove items, then we need to go one pass first to count how
|
||||
// many items we will insert before we allocate the fixed array.
|
||||
for (const char* item = enumeration->next(nullptr, status);
|
||||
U_SUCCESS(status) && item != nullptr;
|
||||
item = enumeration->next(nullptr, status)) {
|
||||
if (unicode_key != nullptr) {
|
||||
item = uloc_toUnicodeLocaleType(unicode_key, item);
|
||||
}
|
||||
if (removes.find(item) == removes.end()) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
enumeration->reset(status);
|
||||
} else {
|
||||
count = enumeration->count(status);
|
||||
}
|
||||
Handle<FixedArray> fixed_array = factory->NewFixedArray(count);
|
||||
|
||||
int32_t index = 0;
|
||||
for (const char* item = enumeration->next(nullptr, status);
|
||||
U_SUCCESS(status) && item != nullptr;
|
||||
item = enumeration->next(nullptr, status)) {
|
||||
if (unicode_key != nullptr) {
|
||||
item = uloc_toUnicodeLocaleType(unicode_key, item);
|
||||
}
|
||||
if (removes.find(item) != removes.end()) {
|
||||
continue;
|
||||
}
|
||||
Handle<String> str = factory->NewStringFromAsciiChecked(item);
|
||||
fixed_array->set(index++, *str);
|
||||
}
|
||||
CHECK(index == count);
|
||||
if (U_FAILURE(status)) {
|
||||
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError),
|
||||
JSArray);
|
||||
}
|
||||
return factory->NewJSArrayWithElements(fixed_array);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
MaybeHandle<JSArray> GetKeywordValuesFromLocale(
|
||||
Isolate* isolate, const char* key, const char* unicode_key,
|
||||
const icu::Locale& locale, const std::set<std::string>& removes) {
|
||||
MaybeHandle<JSArray> GetKeywordValuesFromLocale(Isolate* isolate,
|
||||
const char* key,
|
||||
const char* unicode_key,
|
||||
const icu::Locale& locale,
|
||||
bool (*removes)(const char*),
|
||||
bool commonly_used, bool sort) {
|
||||
Factory* factory = isolate->factory();
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
std::string ext =
|
||||
@ -544,27 +500,43 @@ MaybeHandle<JSArray> GetKeywordValuesFromLocale(
|
||||
}
|
||||
status = U_ZERO_ERROR;
|
||||
std::unique_ptr<icu::StringEnumeration> enumeration(
|
||||
T::getKeywordValuesForLocale(key, locale, true, status));
|
||||
T::getKeywordValuesForLocale(key, locale, commonly_used, status));
|
||||
if (U_FAILURE(status)) {
|
||||
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError),
|
||||
JSArray);
|
||||
}
|
||||
return ToJSArray(isolate, unicode_key, enumeration.get(), removes);
|
||||
return Intl::ToJSArray(isolate, unicode_key, enumeration.get(), removes,
|
||||
sort);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
MaybeHandle<JSArray> CalendarsForLocale(Isolate* isolate,
|
||||
const icu::Locale& icu_locale,
|
||||
bool commonly_used, bool sort) {
|
||||
return GetKeywordValuesFromLocale<icu::Calendar>(
|
||||
isolate, "calendar", "ca", icu_locale, nullptr, commonly_used, sort);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MaybeHandle<JSArray> JSLocale::Calendars(Isolate* isolate,
|
||||
Handle<JSLocale> locale) {
|
||||
icu::Locale icu_locale(*(locale->icu_locale().raw()));
|
||||
return GetKeywordValuesFromLocale<icu::Calendar>(
|
||||
isolate, "calendar", "ca", icu_locale, std::set<std::string>());
|
||||
return CalendarsForLocale(isolate, icu_locale, true, false);
|
||||
}
|
||||
|
||||
MaybeHandle<JSArray> Intl::AvailableCalendars(Isolate* isolate) {
|
||||
icu::Locale icu_locale("und");
|
||||
return CalendarsForLocale(isolate, icu_locale, false, true);
|
||||
}
|
||||
|
||||
MaybeHandle<JSArray> JSLocale::Collations(Isolate* isolate,
|
||||
Handle<JSLocale> locale) {
|
||||
icu::Locale icu_locale(*(locale->icu_locale().raw()));
|
||||
const std::set<std::string> removes({"standard", "search"});
|
||||
return GetKeywordValuesFromLocale<icu::Collator>(isolate, "collations", "co",
|
||||
icu_locale, removes);
|
||||
return GetKeywordValuesFromLocale<icu::Collator>(
|
||||
isolate, "collations", "co", icu_locale, Intl::RemoveCollation, true,
|
||||
false);
|
||||
}
|
||||
|
||||
MaybeHandle<JSArray> JSLocale::HourCycles(Isolate* isolate,
|
||||
@ -693,8 +665,7 @@ MaybeHandle<Object> JSLocale::TimeZones(Isolate* isolate,
|
||||
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError),
|
||||
JSArray);
|
||||
}
|
||||
return ToJSArray(isolate, nullptr, enumeration.get(),
|
||||
std::set<std::string>());
|
||||
return Intl::ToJSArray(isolate, nullptr, enumeration.get(), nullptr, true);
|
||||
}
|
||||
|
||||
MaybeHandle<JSObject> JSLocale::TextInfo(Isolate* isolate,
|
||||
|
@ -173,27 +173,11 @@ std::map<const std::string, icu::MeasureUnit> CreateUnitMap() {
|
||||
int32_t total = icu::MeasureUnit::getAvailable(nullptr, 0, status);
|
||||
CHECK(U_FAILURE(status));
|
||||
status = U_ZERO_ERROR;
|
||||
// See the list in ecma402 #sec-issanctionedsimpleunitidentifier
|
||||
std::set<std::string> sanctioned(
|
||||
{"acre", "bit", "byte",
|
||||
"celsius", "centimeter", "day",
|
||||
"degree", "fahrenheit", "fluid-ounce",
|
||||
"foot", "gallon", "gigabit",
|
||||
"gigabyte", "gram", "hectare",
|
||||
"hour", "inch", "kilobit",
|
||||
"kilobyte", "kilogram", "kilometer",
|
||||
"liter", "megabit", "megabyte",
|
||||
"meter", "mile", "mile-scandinavian",
|
||||
"millimeter", "milliliter", "millisecond",
|
||||
"minute", "month", "ounce",
|
||||
"percent", "petabyte", "pound",
|
||||
"second", "stone", "terabit",
|
||||
"terabyte", "week", "yard",
|
||||
"year"});
|
||||
std::vector<icu::MeasureUnit> units(total);
|
||||
total = icu::MeasureUnit::getAvailable(units.data(), total, status);
|
||||
CHECK(U_SUCCESS(status));
|
||||
std::map<const std::string, icu::MeasureUnit> map;
|
||||
std::set<std::string> sanctioned(Intl::SanctionedSimpleUnits());
|
||||
for (auto it = units.begin(); it != units.end(); ++it) {
|
||||
// Need to skip none/percent
|
||||
if (sanctioned.count(it->getSubtype()) > 0 &&
|
||||
|
11
test/intl/enumeration/calendar-sorted.js
Normal file
11
test/intl/enumeration/calendar-sorted.js
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
// Test the return items of calendar is sorted
|
||||
let name = "calendar";
|
||||
let items = Intl.supportedValuesOf(name);
|
||||
assertEquals([...items].sort(), items,
|
||||
"return value of Intl.supportedValuesOf('" + name + "') should be sorted");
|
14
test/intl/enumeration/callendar-syntax-valid.js
Normal file
14
test/intl/enumeration/callendar-syntax-valid.js
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
// Test the return items of calendar fit 'type'
|
||||
let regex = /^[a-zA-Z0-9]{3,8}(-[a-zA-Z0-9]{3,8})*$/;
|
||||
Intl.supportedValuesOf("calendar").forEach(
|
||||
function(calendar) {
|
||||
assertTrue(regex.test(calendar),
|
||||
"Intl.supportedValuesOf('calendar') return " + calendar +
|
||||
" which does not meet 'type: alphanum{3,8}(sep alphanum{3,8})*'");
|
||||
});
|
11
test/intl/enumeration/collation-sorted.js
Normal file
11
test/intl/enumeration/collation-sorted.js
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
// Test the return items of collation is sorted
|
||||
let name = "collation";
|
||||
let items = Intl.supportedValuesOf(name);
|
||||
assertEquals([...items].sort(), items,
|
||||
"return value of Intl.supportedValuesOf('" + name + "') should be sorted");
|
14
test/intl/enumeration/collation-syntax-valid.js
Normal file
14
test/intl/enumeration/collation-syntax-valid.js
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
// Test the return items of collation fit 'type'
|
||||
let regex = /^[a-zA-Z0-9]{3,8}(-[a-zA-Z0-9]{3,8})*$/;
|
||||
Intl.supportedValuesOf("collation").forEach(
|
||||
function(collation) {
|
||||
assertTrue(regex.test(collation),
|
||||
"Intl.supportedValuesOf('collation') return " + collation +
|
||||
" which does not meet 'type: alphanum{3,8}(sep alphanum{3,8})*'");
|
||||
});
|
11
test/intl/enumeration/currency-sorted.js
Normal file
11
test/intl/enumeration/currency-sorted.js
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
// Test the return items of currency is sorted
|
||||
let name = "currency";
|
||||
let items = Intl.supportedValuesOf(name);
|
||||
assertEquals([...items].sort(), items,
|
||||
"return value of Intl.supportedValuesOf('" + name + "') should be sorted");
|
14
test/intl/enumeration/currency-syntax-valid.js
Normal file
14
test/intl/enumeration/currency-syntax-valid.js
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
// Test the return items of currency fit 'type'
|
||||
let regex = /^[A-Z]{3}$/;
|
||||
Intl.supportedValuesOf("currency").forEach(
|
||||
function(currency) {
|
||||
assertTrue(regex.test(currency),
|
||||
"Intl.supportedValuesOf('currency') return " + currency +
|
||||
" which does not meet 'alpha{3}'");
|
||||
});
|
20
test/intl/enumeration/numberingSystem-no-algorithm.js
Normal file
20
test/intl/enumeration/numberingSystem-no-algorithm.js
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
// Chrome filter out data of algorithm numberingSystems so we need to test none
|
||||
// of them got returned.
|
||||
let name = "numberingSystem";
|
||||
let items = Intl.supportedValuesOf(name);
|
||||
|
||||
function verifyNoAlgorithm(nu) {
|
||||
assertTrue(items.indexOf(nu) < 0, "should not return '" + nu + "' which is algorithmic");
|
||||
}
|
||||
|
||||
["armn", "armnlow", "cyrl", "ethi", "finance", "geor", "grek", "greklow",
|
||||
"hans", "hansfin", "hant", "hantfin", "hebr", "japn", "japnfin",
|
||||
"roman", "romanlow", "taml", "traditio"].forEach(function(nu) {
|
||||
verifyNoAlgorithm(nu);
|
||||
});
|
11
test/intl/enumeration/numberingSystem-sorted.js
Normal file
11
test/intl/enumeration/numberingSystem-sorted.js
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
// Test the return items of numberingSystem is sorted
|
||||
let name = "numberingSystem";
|
||||
let items = Intl.supportedValuesOf(name);
|
||||
assertEquals([...items].sort(), items,
|
||||
"return value of Intl.supportedValuesOf('" + name + "') should be sorted");
|
14
test/intl/enumeration/numberingSystem-syntax-valid.js
Normal file
14
test/intl/enumeration/numberingSystem-syntax-valid.js
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
// Test the return items of numberingSystem fit 'type'
|
||||
let regex = /^[a-zA-Z0-9]{3,8}(-[a-zA-Z0-9]{3,8})*$/;
|
||||
Intl.supportedValuesOf("numberingSystem").forEach(
|
||||
function(numberingSystem) {
|
||||
assertTrue(regex.test(numberingSystem),
|
||||
"Intl.supportedValuesOf('numberingSystem') return " + numberingSystem +
|
||||
" which does not meet 'type: alphanum{3,8}(sep alphanum{3,8})*'");
|
||||
});
|
12
test/intl/enumeration/supported-values-of-invalid-key.js
Normal file
12
test/intl/enumeration/supported-values-of-invalid-key.js
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
// Test invalid keys
|
||||
["calendars", "collations", "currencies", "numberingSystems", "timeZones", "units",
|
||||
1, 0.3, true, false, {}, [] ].forEach(
|
||||
function(key) {
|
||||
assertThrows(() => Intl.supportedValuesOf(key), RangeError);
|
||||
});
|
7
test/intl/enumeration/supported-values-of-name.js
Normal file
7
test/intl/enumeration/supported-values-of-name.js
Normal file
@ -0,0 +1,7 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
assertEquals("supportedValuesOf", Intl.supportedValuesOf.name);
|
11
test/intl/enumeration/supported-values-of-property.js
Normal file
11
test/intl/enumeration/supported-values-of-property.js
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
let descriptor = Object.getOwnPropertyDescriptor(
|
||||
Intl, "supportedValuesOf");
|
||||
assertTrue(descriptor.writable);
|
||||
assertFalse(descriptor.enumerable);
|
||||
assertTrue(descriptor.configurable);
|
12
test/intl/enumeration/supported-values-of-valid-key.js
Normal file
12
test/intl/enumeration/supported-values-of-valid-key.js
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
// Test valid keys
|
||||
["calendar", "collation", "currency", "numberingSystem", "timeZone", "unit"].forEach(
|
||||
function(key) {
|
||||
assertDoesNotThrow(() => Intl.supportedValuesOf(key));
|
||||
assertEquals("object", typeof Intl.supportedValuesOf(key));
|
||||
});
|
11
test/intl/enumeration/timeZone-sorted.js
Normal file
11
test/intl/enumeration/timeZone-sorted.js
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
// Test the return items of timeZone is sorted
|
||||
let name = "timeZone";
|
||||
let items = Intl.supportedValuesOf(name);
|
||||
assertEquals([...items].sort(), items,
|
||||
"return value of Intl.supportedValuesOf('" + name + "') should be sorted");
|
11
test/intl/enumeration/unit-sorted.js
Normal file
11
test/intl/enumeration/unit-sorted.js
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --harmony_intl_enumeration
|
||||
|
||||
// Test the return items of unit is sorted
|
||||
let name = "unit";
|
||||
let items = Intl.supportedValuesOf(name);
|
||||
assertEquals([...items].sort(), items,
|
||||
"return value of Intl.supportedValuesOf('" + name + "') should be sorted");
|
@ -14,7 +14,7 @@ for (var i = 0; i < a_to_z.length; i++) {
|
||||
locale.calendars.forEach(function(tokens) {
|
||||
assertTrue(regex.test(tokens),
|
||||
locale + ".calendars [" + locale.calendars +
|
||||
"] does not meet 'type: alphanum{3,8}(sep alphanum{3,8})*'");
|
||||
"] but '" + tokens + "' does not meet 'type: alphanum{3,8}(sep alphanum{3,8})*'");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user