Commit e6261d70 authored by Frank Tang's avatar Frank Tang Committed by Commit Bot

[Intl] Changes to new behavior when style is narrow

This is to implement a new change in the proposal
'14.  If style is "narrow" and type is not "unit", throw a RangeError exception.'
in #sec-Intl.ListFormat
See also
https://github.com/tc39/proposal-intl-list-format/issues/16
https://github.com/tc39/proposal-intl-list-format/pull/27
and
https://github.com/tc39/test262/pull/1860

Bug: v8:8302
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: I0a3dc99eeb18082f359c24c472889d8b6e905225
Reviewed-on: https://chromium-review.googlesource.com/c/1277660
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarFrank Tang <ftang@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: 's avatarDaniel Ehrenberg <littledan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56707}
parent 4d07af1a
......@@ -320,6 +320,9 @@ namespace internal {
T(InvalidTypedArrayAlignment, "% of % should be a multiple of %") \
T(InvalidTypedArrayIndex, "Invalid typed array index") \
T(InvalidTypedArrayLength, "Invalid typed array length: %") \
T(IllegalTypeWhileStyleNarrow, \
"When style is 'narrow', 'unit' is the only allowed value for the type " \
"option.") \
T(LetInLexicalBinding, "let is disallowed as a lexically bound name") \
T(LocaleMatcher, "Illegal value for localeMatcher:%") \
T(NormalizationForm, "The normalization form should be one of %.") \
......
......@@ -41,31 +41,29 @@ const char* GetIcuStyleString(JSListFormat::Style style,
return kStandard;
case JSListFormat::Style::SHORT:
return kStandardShort;
// NARROW is now not allowed if type is not unit
// It is impossible to reach because we've already thrown a RangeError
// when style is "narrow" and type is not "unit".
case JSListFormat::Style::NARROW:
// Currently, ListFormat::createInstance on "standard-narrow" will
// fail so we use "standard-short" here.
// See https://unicode.org/cldr/trac/ticket/11254
// TODO(ftang): change to return kStandardNarrow; after the above
// issue fixed in CLDR/ICU.
// CLDR bug: https://unicode.org/cldr/trac/ticket/11254
// ICU bug: https://unicode-org.atlassian.net/browse/ICU-20014
return kStandardShort;
case JSListFormat::Style::COUNT:
UNREACHABLE();
}
case JSListFormat::Type::DISJUNCTION:
switch (style) {
// Currently, ListFormat::createInstance on "or-short" and "or-narrow"
// Currently, ListFormat::createInstance on "or-short"
// will fail so we use "or" here.
// See https://unicode.org/cldr/trac/ticket/11254
// TODO(ftang): change to return kOr, kOrShort or kOrNarrow depend on
// TODO(ftang): change to return kOr or kOrShort depend on
// style after the above issue fixed in CLDR/ICU.
// CLDR bug: https://unicode.org/cldr/trac/ticket/11254
// ICU bug: https://unicode-org.atlassian.net/browse/ICU-20014
case JSListFormat::Style::LONG:
case JSListFormat::Style::SHORT:
case JSListFormat::Style::NARROW:
return kOr;
// NARROW is now not allowed if type is not unit
// It is impossible to reach because we've already thrown a RangeError
// when style is "narrow" and type is not "unit".
case JSListFormat::Style::NARROW:
case JSListFormat::Style::COUNT:
UNREACHABLE();
}
......@@ -178,8 +176,8 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize(
// 10. Set listFormat.[[Style]] to s.
list_format_holder->set_style(style_enum);
// TODO(ftang): There's no spec text for this yet.
// Tracking issue: https://github.com/tc39/proposal-intl-list-format/issues/24
// 12. Let matcher be ? GetOption(options, "localeMatcher", "string", «
// "lookup", "best fit" », "best fit").
const std::vector<const char*> values = {"lookup", "best fit"};
std::unique_ptr<char[]> matcher_str = nullptr;
Intl::MatcherOption matcher = Intl::MatcherOption::kBestFit;
......@@ -194,15 +192,22 @@ MaybeHandle<JSListFormat> JSListFormat::Initialize(
}
}
// 11. Let localeData be %ListFormat%.[[LocaleData]].
// 12. Let r be ResolveLocale(%ListFormat%.[[AvailableLocales]],
// 14. If style is "narrow" and type is not "unit", throw a RangeError
// exception.
if (style_enum == Style::NARROW && type_enum != Type::UNIT) {
THROW_NEW_ERROR(
isolate, NewRangeError(MessageTemplate::kIllegalTypeWhileStyleNarrow),
JSListFormat);
}
// 15. Let r be ResolveLocale(%ListFormat%.[[AvailableLocales]],
// requestedLocales, opt, undefined, localeData).
std::set<std::string> available_locales =
Intl::GetAvailableLocales(ICUService::kListFormatter);
Intl::ResolvedLocale r = Intl::ResolveLocale(isolate, available_locales,
requested_locales, matcher, {});
// 21. Set listFormat.[[Locale]] to r.[[Locale]].
// 24. Set listFormat.[[Locale]] to r.[[Locale]].
Handle<String> locale_str =
isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
list_format_holder->set_locale(*locale_str);
......
......@@ -54,8 +54,7 @@ assertDoesNotThrow(
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {style: 'short'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {style: 'narrow'}));
assertThrows(() => new Intl.ListFormat(['sr'], {style: 'narrow'}), RangeError);
assertThrows(
() => new Intl.ListFormat(['sr'], {style: 'giant'}),
......@@ -67,8 +66,9 @@ assertDoesNotThrow(
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'conjunction', style: 'short'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'conjunction', style: 'narrow'}));
assertThrows(
() => new Intl.ListFormat(['sr'], {type: 'conjunction', style: 'narrow'}),
RangeError);
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'disjunction', style: 'long'}));
......@@ -76,8 +76,9 @@ assertDoesNotThrow(
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'disjunction', style: 'short'}));
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'disjunction', style: 'narrow'}));
assertThrows(
() => new Intl.ListFormat(['sr'], {type: 'disjunction', style: 'narrow'}),
RangeError);
assertDoesNotThrow(
() => new Intl.ListFormat(['sr'], {type: 'unit', style: 'long'}));
......
......@@ -14,13 +14,14 @@ let enLongConjunction = new Intl.ListFormat(
["en"], {style: "long", type: 'conjunction'});
assertEquals('', enLongConjunction.format());
assertEquals('', enLongConjunction.format([]));
assertEquals('', enLongConjunction.format([]));
assertEquals('a', enLongConjunction.format(['a']));
assertEquals('b', enLongConjunction.format(['b']));
assertEquals('a and b', enLongConjunction.format(['a', 'b']));
assertEquals('a, b, and c', enLongConjunction.format(['a', 'b', 'c']));
assertEquals('a, b, c, and d', enLongConjunction.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, and and', enLongConjunction.format(['a', 'b', 'c', 'd', 'and']));
assertEquals('a, b, c, d, and and',
enLongConjunction.format(['a', 'b', 'c', 'd', 'and']));
let enLongDisjunction = new Intl.ListFormat(
["en"], {style: "long", type: 'disjunction'});
......@@ -32,7 +33,8 @@ assertEquals('b', enLongDisjunction.format(['b']));
assertEquals('a or b', enLongDisjunction.format(['a', 'b']));
assertEquals('a, b, or c', enLongDisjunction.format(['a', 'b', 'c']));
assertEquals('a, b, c, or d', enLongDisjunction.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, or or', enLongDisjunction.format(['a', 'b', 'c', 'd', 'or']));
assertEquals('a, b, c, d, or or',
enLongDisjunction.format(['a', 'b', 'c', 'd', 'or']));
let enLongUnit = new Intl.ListFormat(
["en"], {style: "long", type: 'unit'});
......@@ -56,7 +58,8 @@ assertEquals('b', enShortConjunction.format(['b']));
assertEquals('a and b', enShortConjunction.format(['a', 'b']));
assertEquals('a, b, and c', enShortConjunction.format(['a', 'b', 'c']));
assertEquals('a, b, c, and d', enShortConjunction.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, and and', enShortConjunction.format(['a', 'b', 'c', 'd', 'and']));
assertEquals('a, b, c, d, and and',
enShortConjunction.format(['a', 'b', 'c', 'd', 'and']));
let enShortDisjunction = new Intl.ListFormat(
["en"], {style: "short", type: 'disjunction'});
......@@ -82,30 +85,6 @@ assertEquals('a, b, c', enShortUnit.format(['a', 'b', 'c']));
assertEquals('a, b, c, d', enShortUnit.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, or', enShortUnit.format(['a', 'b', 'c', 'd', 'or']));
let enNarrowConjunction = new Intl.ListFormat(
["en"], {style: "narrow", type: 'conjunction'});
assertEquals('', enNarrowConjunction.format());
assertEquals('', enNarrowConjunction.format([]));
assertEquals('a', enNarrowConjunction.format(['a']));
assertEquals('b', enNarrowConjunction.format(['b']));
assertEquals('a and b', enNarrowConjunction.format(['a', 'b']));
assertEquals('a, b, and c', enNarrowConjunction.format(['a', 'b', 'c']));
assertEquals('a, b, c, and d', enNarrowConjunction.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, and and', enNarrowConjunction.format(['a', 'b', 'c', 'd', 'and']));
let enNarrowDisjunction = new Intl.ListFormat(
["en"], {style: "narrow", type: 'disjunction'});
assertEquals('', enNarrowDisjunction.format());
assertEquals('', enNarrowDisjunction.format([]));
assertEquals('a', enNarrowDisjunction.format(['a']));
assertEquals('b', enNarrowDisjunction.format(['b']));
assertEquals('a or b', enNarrowDisjunction.format(['a', 'b']));
assertEquals('a, b, or c', enNarrowDisjunction.format(['a', 'b', 'c']));
assertEquals('a, b, c, or d', enNarrowDisjunction.format(['a', 'b', 'c', 'd']));
assertEquals('a, b, c, d, or or', enNarrowDisjunction.format(['a', 'b', 'c', 'd', 'or']));
let enNarrowUnit = new Intl.ListFormat(
["en"], {style: "narrow", type: 'unit'});
......
......@@ -77,16 +77,22 @@ testFormatter(new Intl.ListFormat());
testFormatter(new Intl.ListFormat(["en"]));
testFormatter(new Intl.ListFormat(["en"], {style: 'long'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow'}));
assertThrows(() => new Intl.ListFormat(["en"], {style: 'narrow'}), RangeError);
testFormatter(new Intl.ListFormat(["en"], {type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {type: 'unit'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'long', type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short', type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow', type: 'conjunction'}));
testFormatter(
new Intl.ListFormat(["en"], {style: 'short', type: 'conjunction'}));
assertThrows(
() => new Intl.ListFormat(
["en"], {style: 'narrow', type: 'conjunction'}), RangeError);
testFormatter(new Intl.ListFormat(["en"], {style: 'long', type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short', type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow', type: 'disjunction'}));
testFormatter(
new Intl.ListFormat(["en"], {style: 'short', type: 'disjunction'}));
assertThrows(
() => new Intl.ListFormat(
["en"], {style: 'narrow', type: 'disjunction'}), RangeError);
testFormatter(new Intl.ListFormat(["en"], {style: 'long', type: 'unit'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short', type: 'unit'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow', type: 'unit'}));
......@@ -48,16 +48,19 @@ testFormatter(new Intl.ListFormat());
testFormatter(new Intl.ListFormat(["en"]));
testFormatter(new Intl.ListFormat(["en"], {style: 'long'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow'}));
assertThrows(() => new Intl.ListFormat(
["en"], {style: 'narrow'}), RangeError);
testFormatter(new Intl.ListFormat(["en"], {type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {type: 'unit'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'long', type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short', type: 'conjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow', type: 'conjunction'}));
assertThrows(() => new Intl.ListFormat(
["en"], {style: 'narrow', type: 'conjunction'}), RangeError);
testFormatter(new Intl.ListFormat(["en"], {style: 'long', type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short', type: 'disjunction'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow', type: 'disjunction'}));
assertThrows(() => new Intl.ListFormat(
["en"], {style: 'narrow', type: 'disjunction'}), RangeError);
testFormatter(new Intl.ListFormat(["en"], {style: 'long', type: 'unit'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'short', type: 'unit'}));
testFormatter(new Intl.ListFormat(["en"], {style: 'narrow', type: 'unit'}));
......@@ -21,16 +21,6 @@ assertEquals(
(new Intl.ListFormat(['sr'], {style: 'short'}))
.resolvedOptions().type);
assertEquals(
'narrow',
(new Intl.ListFormat(['sr'], {style: 'narrow'}))
.resolvedOptions().style);
assertEquals(
'conjunction',
(new Intl.ListFormat(['sr'], {style: 'narrow'}))
.resolvedOptions().type);
assertEquals(
'long',
(new Intl.ListFormat(['sr'], {style: 'long'}))
......@@ -72,33 +62,43 @@ assertEquals(
.resolvedOptions().style);
assertEquals(
'disjunction',
(new Intl.ListFormat(['sr'], {style: 'long', type: 'disjunction'}))
'conjunction',
(new Intl.ListFormat(['sr'], {style: 'long', type: 'conjunction'}))
.resolvedOptions().type);
assertEquals(
'long',
(new Intl.ListFormat(['sr'], {style: 'long', type: 'disjunction'}))
(new Intl.ListFormat(['sr'], {style: 'long', type: 'conjunction'}))
.resolvedOptions().style);
assertEquals(
'disjunction',
(new Intl.ListFormat(['sr'], {style: 'short', type: 'disjunction'}))
'conjunction',
(new Intl.ListFormat(['sr'], {style: 'short', type: 'conjunction'}))
.resolvedOptions().type);
assertEquals(
'short',
(new Intl.ListFormat(['sr'], {style: 'short', type: 'disjunction'}))
(new Intl.ListFormat(['sr'], {style: 'short', type: 'conjunction'}))
.resolvedOptions().style);
assertEquals(
'disjunction',
(new Intl.ListFormat(['sr'], {style: 'narrow', type: 'disjunction'}))
(new Intl.ListFormat(['sr'], {style: 'long', type: 'disjunction'}))
.resolvedOptions().type);
assertEquals(
'narrow',
(new Intl.ListFormat(['sr'], {style: 'narrow', type: 'disjunction'}))
'long',
(new Intl.ListFormat(['sr'], {style: 'long', type: 'disjunction'}))
.resolvedOptions().style);
assertEquals(
'disjunction',
(new Intl.ListFormat(['sr'], {style: 'short', type: 'disjunction'}))
.resolvedOptions().type);
assertEquals(
'short',
(new Intl.ListFormat(['sr'], {style: 'short', type: 'disjunction'}))
.resolvedOptions().style);
assertEquals(
......
// Copyright 2015 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-list-format
new Intl.ListFormat("en", {style: 'narrow'})
*%(basename)s:7: RangeError: When style is 'narrow', 'unit' is the only allowed value for the type option.
new Intl.ListFormat("en", {style: 'narrow'})
^
RangeError: When style is 'narrow', 'unit' is the only allowed value for the type option.
at new ListFormat (<anonymous>)
at *%(basename)s:7:1
......@@ -49,4 +49,8 @@
'*': [SKIP],
}], # variant == code_serializer
['no_i18n == True', {
'fail/list-format*': [SKIP],
}], # no_i18n == True
]
......@@ -613,6 +613,15 @@
# https://bugs.chromium.org/p/v8/issues/detail?id=7871
'intl402/ListFormat/prototype/formatToParts/en-us-disjunction': [FAIL],
# The following is due to spec changes in
# https://github.com/tc39/proposal-intl-list-format/pull/27
# and will be addressed after pulling new test262 which include the tests fixes in
# https://github.com/tc39/test262/pull/1860
# see https://bugs.chromium.org/p/v8/issues/detail?id=8302
'intl402/ListFormat/constructor/constructor/options-style-valid': [FAIL],
'intl402/ListFormat/prototype/format/en-us-narrow': [FAIL],
'intl402/ListFormat/prototype/formatToParts/en-us-narrow': [FAIL],
######################## NEEDS INVESTIGATION ###########################
# These test failures are specific to the intl402 suite and need investigation
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment