Commit 830fb817 authored by Frank Tang's avatar Frank Tang Committed by V8 LUCI CQ

[intl] Sync to PR100 of intl-numberformat-v3

Remove the range check of formatRange, formatRangeToParts on
NumberFormat and selectRange on PluralRules

Bug: v8:10776
Change-Id: Ifede7d61db6414d5b338b22bd188406e5f7d98b7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3779041Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81984}
parent a06680e7
...@@ -983,8 +983,6 @@ BUILTIN(PluralRulesPrototypeSelectRange) { ...@@ -983,8 +983,6 @@ BUILTIN(PluralRulesPrototypeSelectRange) {
Object::ToNumber(isolate, end)); Object::ToNumber(isolate, end));
// 6. Return ! ResolvePluralRange(pr, x, y). // 6. Return ! ResolvePluralRange(pr, x, y).
// Inside ResolvePluralRange
// 5. If x is NaN or y is NaN, throw a RangeError exception.
if (x->IsNaN()) { if (x->IsNaN()) {
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewRangeError(MessageTemplate::kInvalid, isolate, NewRangeError(MessageTemplate::kInvalid,
...@@ -996,16 +994,9 @@ BUILTIN(PluralRulesPrototypeSelectRange) { ...@@ -996,16 +994,9 @@ BUILTIN(PluralRulesPrototypeSelectRange) {
isolate->factory()->endRange_string(), y)); isolate->factory()->endRange_string(), y));
} }
// 6. If x > y, throw a RangeError exception.
double x_double = x->Number();
double y_double = y->Number();
if (x_double > y_double) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewRangeError(MessageTemplate::kInvalid, x, y));
}
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, JSPluralRules::ResolvePluralRange(isolate, plural_rules, isolate, JSPluralRules::ResolvePluralRange(isolate, plural_rules,
x_double, y_double)); x->Number(), y->Number()));
} }
BUILTIN(PluralRulesSupportedLocalesOf) { BUILTIN(PluralRulesSupportedLocalesOf) {
......
...@@ -1670,244 +1670,6 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate, ...@@ -1670,244 +1670,6 @@ MaybeHandle<JSNumberFormat> JSNumberFormat::New(Isolate* isolate,
namespace { namespace {
// StrDecimalLiteral is a helper class which is only use in step 2a ("y < x")
// of PartitionNumberRangePattern while x and y are equal in double precision
// but maybe differ in highier precision. It is only used by
// IntlMathmeticalValue::IsLessThan to compare one value is less than the other.
// Both x and y are String following the syntax of StrDecimalLiteral
// which is (+|-)?((\d+(.\d*)?)|(.\d+))([eE](+|-)?\d+)?
class V8_NODISCARD StrDecimalLiteral {
public:
bool IsLessThan(const StrDecimalLiteral& y) const;
// Factory method
static StrDecimalLiteral From(Isolate* isolate, Handle<String> string);
private:
bool negative_;
double exp_value_;
int integer_start_pos_; // the position of the first digit in the integer
// part.
int integer_end_pos_; // 1 beyond the position of the last digit in the
// integer part.
int fraction_start_pos_; // the position of the first digit in the fraction
// part.
int fraction_end_pos_; // 1 beyond the position of the last digit in the
// fraction part.
Handle<String> str_;
StrDecimalLiteral();
int Digit(int index) const;
int length() const {
return integer_end_pos_ - integer_start_pos_ + fraction_end_pos_ -
fraction_start_pos_;
}
template <typename Char>
static StrDecimalLiteral Parse(const base::Vector<const Char>& src);
};
StrDecimalLiteral::StrDecimalLiteral()
: negative_(false),
exp_value_(0),
integer_start_pos_(0),
integer_end_pos_(0),
fraction_start_pos_(0),
fraction_end_pos_(0) {}
template <typename Char>
StrDecimalLiteral StrDecimalLiteral::Parse(
const base::Vector<const Char>& src) {
StrDecimalLiteral result;
if (src.length() == 0) return result;
int i = 0;
uint16_t ch = static_cast<uint16_t>(src.at(i));
// Scan the sign
if (ch == '-') {
result.negative_ = true;
i++;
} else if (ch == '+') {
i++;
}
// Scan the Integer part
// Skip leading '0'
for (; i < src.length() && src.at(i) == '0'; i++) {
}
result.integer_start_pos_ = i;
// Scan 0-9
for (; i < src.length(); i++) {
ch = static_cast<uint16_t>(src.at(i));
if (!('0' <= ch && ch <= '9')) break;
}
result.integer_end_pos_ = i;
// We normalize to value in the range [0.1, 1.0) x 10 ^ $exp_value_
// For example, if the input is 123.45e6 we will turn it into
// 123.45e6 exp_value_ = 3 at this point. Will add 6 to become 9 later.
// ^ ^
// | +------ integer_end_pos_
// +--------- integer_start_pos_
// So conceptually we know we have 0.123 x10^3 after parsed the "123." part.
result.exp_value_ =
static_cast<double>(result.integer_end_pos_ - result.integer_start_pos_);
// If there are no fractional nor exponment, then
if (i == src.length()) {
// Trim trailing '0' in Integer part.
while (result.integer_start_pos_ < result.integer_end_pos_ &&
src.at(result.integer_end_pos_ - 1) == '0') {
result.integer_end_pos_--;
}
// For example, if we have input as 1230000e4, we will now have
// 1230000e4 exp_value_ = 7
// ^ ^
// | +------ integer_end_pos_
// +--------- integer_start_pos_
// This part is unnecessary for correctness but to skip unnecessary later
// comparsion for performance.
// So conceptually we know we have 0.123 x10^7 after parsed "1230000".
return result;
}
if (src.at(i) == '.') {
i++;
// Scan the Fraction part
for (result.fraction_start_pos_ = i; i < src.length(); i++) {
ch = static_cast<uint16_t>(src.at(i));
if (!('0' <= ch && ch <= '9')) break;
}
result.fraction_end_pos_ = i;
// For example, if the input is 123.45e6 we will turn it into
// 123.45e6 exp_value_ = 3 at this point. Will add 6 to become 9 later.
// ^ ^^ ^
// | || +--- fraction_end_pos_
// | |+----- fraction_start_pos_
// | +------ integer_end_pos_
// +--------- integer_start_pos_
// So conceptually we know we have 0.123456 x10^3 after parsed "123.45".
}
// Scan Exponent
if (i < src.length()) {
ch = static_cast<uint16_t>(src.at(i));
if (ch == 'e' || ch == 'E') {
i++;
if (i < src.length()) {
double exponent_sign = 1.0;
ch = static_cast<uint16_t>(src.at(i));
if (ch == '-') {
exponent_sign = -1.0;
i++;
} else if (ch == '+') {
i++;
}
double scan_exponent = 0;
for (; i < src.length(); i++) {
ch = src.at(i);
if (!('0' <= ch && ch <= '9')) {
break;
}
scan_exponent *= 10;
scan_exponent += ch - '0';
}
CHECK_EQ(i, src.length());
result.exp_value_ += exponent_sign * scan_exponent;
}
}
}
// If we do not have Integer part, adjust exp_value_ by removing leading '0'
// in Fraction part.
if (result.integer_start_pos_ == result.integer_end_pos_) {
while (result.fraction_start_pos_ < result.fraction_end_pos_ &&
src.at(result.fraction_start_pos_) == '0') {
result.fraction_start_pos_++;
result.exp_value_--;
}
// For example, if the input is .00045e9 we will turn it into
// .00045e9 exp_value_ = 6
// ^ ^ ^
// | | +--- fraction_end_pos_
// | +----- fraction_start_pos_
// +--------- integer_end_pos_
// +--------- integer_start_pos_
// So conceptually we know we have 0.456 x10^6 instead of 0.000456 x 10^9
}
// Trim trialing '0' in Fraction part
// For example, if the input is .0004500e9 the following while loop will
// turn it into
// .0004500e9 exp_value_ = 6
// ^ ^ ^
// | | +--- fraction_end_pos_
// | +----- fraction_start_pos_
// +--------- integer_end_pos_
// +--------- integer_start_pos_
// So conceptually we know we have 0.456 x 10^6 instead of 0.45600 x 10^6.
while (result.fraction_start_pos_ < result.fraction_end_pos_ &&
src.at(result.fraction_end_pos_ - 1) == '0') {
result.fraction_end_pos_--;
}
// If there are no fraction in the input, trim trailing '0' in Integer part.
if (result.fraction_start_pos_ == result.fraction_end_pos_) {
// For example, if the input is .0004500e9 the following while loop will
// turn it into
// 123000e9 exp_value_ = 15
// ^ ^ ^
// | | +--- fraction_end_pos_
// | | +--- fraction_start_pos_
// | +------ integer_end_pos_
// +--------- integer_start_pos_
// So conceptually we know we have 0.123 x 10^15 instead of 0.123000 x 10^15
while (result.integer_start_pos_ < result.integer_end_pos_ &&
src.at(result.integer_end_pos_ - 1) == '0') {
result.integer_end_pos_--;
}
}
DCHECK_EQ(i, src.length());
return result;
}
StrDecimalLiteral StrDecimalLiteral::From(Isolate* isolate,
Handle<String> string) {
string = String::Flatten(isolate, string);
DisallowGarbageCollection no_gc;
String::FlatContent flat = string->GetFlatContent(no_gc);
StrDecimalLiteral result;
if (flat.IsOneByte()) {
result = Parse(flat.ToOneByteVector());
} else {
result = Parse(flat.ToUC16Vector());
}
result.str_ = string;
return result;
}
int StrDecimalLiteral::Digit(int index) const {
if (index < integer_end_pos_ - integer_start_pos_) {
return str_->Get(index + integer_start_pos_) - '0';
}
if (index < length()) {
return str_->Get(index - (integer_end_pos_ - integer_start_pos_) +
fraction_start_pos_) -
'0';
}
return 0;
}
bool StrDecimalLiteral::IsLessThan(const StrDecimalLiteral& y) const {
if (negative_ != y.negative_) {
return negative_;
}
if (exp_value_ != y.exp_value_) {
return (exp_value_ < y.exp_value_) != negative_;
}
int length = std::max(y.length(), this->length());
for (int i = 0; i < length; i++) {
int dx = Digit(i);
int dy = y.Digit(i);
if (dx != dy) {
return (dx < dy) != negative_;
}
}
return false;
}
icu::number::FormattedNumber FormatDecimalString( icu::number::FormattedNumber FormatDecimalString(
Isolate* isolate, Isolate* isolate,
const icu::number::LocalizedNumberFormatter& number_format, const icu::number::LocalizedNumberFormatter& number_format,
...@@ -1927,23 +1689,8 @@ icu::number::FormattedNumber FormatDecimalString( ...@@ -1927,23 +1689,8 @@ icu::number::FormattedNumber FormatDecimalString(
} // namespace } // namespace
bool IntlMathematicalValue::IsNegative() const {
if (value_->IsBigInt()) {
return Handle<BigInt>::cast(value_)->IsNegative();
}
return approx_ < 0;
}
bool IntlMathematicalValue::IsMinusZero() const {
return ::v8::internal::IsMinusZero(approx_);
}
bool IntlMathematicalValue::IsNaN() const { return value_->IsNaN(); } bool IntlMathematicalValue::IsNaN() const { return value_->IsNaN(); }
bool IntlMathematicalValue::IsInfinity() const {
return value_->IsNumber() && std::isinf(approx_);
}
MaybeHandle<String> IntlMathematicalValue::ToString(Isolate* isolate) const { MaybeHandle<String> IntlMathematicalValue::ToString(Isolate* isolate) const {
Handle<String> string; Handle<String> string;
if (value_->IsNumber()) { if (value_->IsNumber()) {
...@@ -2068,44 +1815,6 @@ Maybe<icu::number::FormattedNumberRange> IntlMathematicalValue::FormatRange( ...@@ -2068,44 +1815,6 @@ Maybe<icu::number::FormattedNumberRange> IntlMathematicalValue::FormatRange(
return Just(std::move(result)); return Just(std::move(result));
} }
bool IntlMathematicalValue::IsLessThan(Isolate* isolate,
const IntlMathematicalValue& y) const {
DCHECK(IsMathematicalValue());
DCHECK(y.IsMathematicalValue());
if (approx_ != y.approx_) {
return approx_ < y.approx_;
}
DCHECK(value_->IsNumber() || value_->IsString() || value_->IsBigInt());
DCHECK(y.value_->IsNumber() || y.value_->IsString() || y.value_->IsBigInt());
if (value_->IsNumber() && y.value_->IsNumber()) {
// If both are Number, return false since we have no more precision than
// approx_. So we have to conclude they are equal and therefore false for
// IsLessThan.
return false;
}
if (value_->IsBigInt()) {
Handle<BigInt> x_bigint = Handle<BigInt>::cast(value_);
if (y.value_->IsBigInt()) {
return ComparisonResult::kLessThan ==
BigInt::CompareToBigInt(x_bigint, Handle<BigInt>::cast(y.value_));
}
if (y.value_->IsNumber()) {
return ComparisonResult::kLessThan ==
BigInt::CompareToNumber(x_bigint, y.value_);
}
}
if (value_->IsNumber() && y.value_->IsBigInt()) {
return ComparisonResult::kGreaterThan ==
BigInt::CompareToNumber(Handle<BigInt>::cast(y.value_), value_);
}
// Both value_ and y.value_ should be String now.
Handle<String> x_str = ToString(isolate).ToHandleChecked();
Handle<String> y_str = y.ToString(isolate).ToHandleChecked();
return StrDecimalLiteral::From(isolate, x_str)
.IsLessThan(StrDecimalLiteral::From(isolate, y_str));
}
namespace { namespace {
// Return the index of the end of leading white space or line terminator // Return the index of the end of leading white space or line terminator
// and the index of the start of trailing white space or line terminator. // and the index of the start of trailing white space or line terminator.
...@@ -2497,64 +2206,6 @@ MaybeHandle<T> PartitionNumberRangePattern(Isolate* isolate, ...@@ -2497,64 +2206,6 @@ MaybeHandle<T> PartitionNumberRangePattern(Isolate* isolate,
MaybeHandle<T>()); MaybeHandle<T>());
} }
// 2. If x is a mathematical value, then
if (x.IsMathematicalValue()) {
// a. If y is a mathematical value and y < x, throw a RangeError exception.
if (y.IsMathematicalValue()) {
if (y.IsLessThan(isolate, x)) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalid, start, end),
MaybeHandle<T>());
}
}
// b. Else if y is negative-infinity, throw a RangeError exception.
if (y.IsNegativeInfinity()) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalid, start, end),
MaybeHandle<T>());
}
// c. Else if y is -0 and x ≥ 0, throw a RangeError exception.
if (y.IsMinusZero() && !x.IsNegative()) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalid, start, end),
MaybeHandle<T>());
}
// Else if x is positive-infinity, then
} else if (x.IsPositiveInfinity()) {
// If y is a mathematical value, throw a RangeError exception.
if (y.IsMathematicalValue()) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalid, start, end),
MaybeHandle<T>());
}
// b. Else if y is negative-infinity, throw a RangeError exception.
if (y.IsNegativeInfinity()) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalid, start, end),
MaybeHandle<T>());
}
// c. Else if y is negative-zero, throw a RangeError exception.
if (y.IsMinusZero()) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalid, start, end),
MaybeHandle<T>());
}
// 4. Else if x is negative-zero, then
} else if (x.IsMinusZero()) {
// a. If y is a mathematical value and y < 0, throw a RangeError exception.
if (y.IsMathematicalValue() && y.IsNegative()) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalid, start, end),
MaybeHandle<T>());
}
// b. Else if y is negative-infinity, throw a RangeError exception.
if (y.IsNegativeInfinity()) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate, NewRangeError(MessageTemplate::kInvalid, start, end),
MaybeHandle<T>());
}
}
Maybe<icu::number::LocalizedNumberRangeFormatter> maybe_range_formatter = Maybe<icu::number::LocalizedNumberRangeFormatter> maybe_range_formatter =
JSNumberFormat::GetRangeFormatter( JSNumberFormat::GetRangeFormatter(
isolate, number_format->locale(), isolate, number_format->locale(),
......
...@@ -117,19 +117,6 @@ class V8_NODISCARD IntlMathematicalValue { ...@@ -117,19 +117,6 @@ class V8_NODISCARD IntlMathematicalValue {
public: public:
IntlMathematicalValue() : approx_(0) {} IntlMathematicalValue() : approx_(0) {}
V8_EXPORT_PRIVATE bool IsNaN() const; V8_EXPORT_PRIVATE bool IsNaN() const;
V8_EXPORT_PRIVATE bool IsMinusZero() const;
V8_EXPORT_PRIVATE bool IsNegative() const;
V8_EXPORT_PRIVATE bool IsNegativeInfinity() const {
return IsNegative() && IsInfinity();
}
V8_EXPORT_PRIVATE bool IsPositiveInfinity() const {
return !IsNegative() && IsInfinity();
}
V8_EXPORT_PRIVATE bool IsMathematicalValue() const {
return !(IsNaN() || IsMinusZero() || IsInfinity());
}
V8_EXPORT_PRIVATE bool IsLessThan(Isolate* isolate,
const IntlMathematicalValue& y) const;
V8_EXPORT_PRIVATE static Maybe<IntlMathematicalValue> From( V8_EXPORT_PRIVATE static Maybe<IntlMathematicalValue> From(
Isolate* isolate, Handle<Object> value); Isolate* isolate, Handle<Object> value);
...@@ -149,7 +136,6 @@ class V8_NODISCARD IntlMathematicalValue { ...@@ -149,7 +136,6 @@ class V8_NODISCARD IntlMathematicalValue {
Handle<Object> value_; // Number, BigInt or String Handle<Object> value_; // Number, BigInt or String
Maybe<icu::Formattable> ToFormattable(Isolate* isolate) const; Maybe<icu::Formattable> ToFormattable(Isolate* isolate) const;
MaybeHandle<String> ToString(Isolate* isolate) const; MaybeHandle<String> ToString(Isolate* isolate) const;
V8_EXPORT_PRIVATE bool IsInfinity() const;
}; };
} // namespace internal } // namespace internal
......
...@@ -16,45 +16,41 @@ assertThrows(() => { df.formatRange("1", "-0b1111") }, RangeError); ...@@ -16,45 +16,41 @@ assertThrows(() => { df.formatRange("1", "-0b1111") }, RangeError);
assertThrows(() => { df.formatRange("1", "-0o7654") }, RangeError); assertThrows(() => { df.formatRange("1", "-0o7654") }, RangeError);
assertThrows(() => { df.formatRange("1", "-0xabcde") }, RangeError); assertThrows(() => { df.formatRange("1", "-0xabcde") }, RangeError);
// 2. If x is a mathematical value, then assertDoesNotThrow(() => { df.formatRange(
// 2a. If y is a mathematical value and y < x, throw a RangeError exception.
assertThrows(() => { df.formatRange(
" +1234567890123456789012345678901234567890123456789012345678901 ", " +1234567890123456789012345678901234567890123456789012345678901 ",
" +123456789012345678901234567890123456789012345678901234567890 ") }, RangeError); " +123456789012345678901234567890123456789012345678901234567890 ") });
assertThrows(() => { df.formatRange( assertDoesNotThrow(() => { df.formatRange(
" +123456789012345678901234567890.123456789012345678901234567890e25 ", " +123456789012345678901234567890.123456789012345678901234567890e25 ",
" +12345678901234567890.1234567890123456789012345678901234567890e25 ") }, RangeError); " +12345678901234567890.1234567890123456789012345678901234567890e25 ")});
assertThrows(() => { df.formatRange( assertDoesNotThrow(() => { df.formatRange(
" +12345678901234567890.1234567890123456789012345678901234567890e35 ", " +12345678901234567890.1234567890123456789012345678901234567890e35 ",
" +123456789012345678901234567890.123456789012345678901234567890e24 ") }, RangeError); " +123456789012345678901234567890.123456789012345678901234567890e24 ")});
assertThrows(() => { df.formatRange( assertDoesNotThrow(() => { df.formatRange(
" -123456789012345678901234567890123456789012345678901234567890 ", " -123456789012345678901234567890123456789012345678901234567890 ",
" -1234567890123456789012345678901234567890123456789012345678901 ") }, RangeError); " -1234567890123456789012345678901234567890123456789012345678901 ")});
assertThrows(() => { df.formatRange( assertDoesNotThrow(() => { df.formatRange(
" -12345678901234567890.1234567890123456789012345678901234567890e25 ", " -12345678901234567890.1234567890123456789012345678901234567890e25 ",
" -123456789012345678901234567890.123456789012345678901234567890e25 ") }, RangeError); " -123456789012345678901234567890.123456789012345678901234567890e25 ")});
assertThrows(() => { df.formatRange( assertDoesNotThrow(() => { df.formatRange(
" -123456789012345678901234567890.123456789012345678901234567890e24 ", " -123456789012345678901234567890.123456789012345678901234567890e24 ",
" -12345678901234567890.1234567890123456789012345678901234567890e35 ") }, RangeError); " -12345678901234567890.1234567890123456789012345678901234567890e35 ")});
assertThrows(() => { df.formatRange( assertDoesNotThrow(() => { df.formatRange(
" +.1234567890123456789012345678901234567890123456789012345678901 ", " +.1234567890123456789012345678901234567890123456789012345678901 ",
" +.123456789012345678901234567890123456789012345678901234567890 ") }, RangeError); " +.123456789012345678901234567890123456789012345678901234567890 ")});
assertThrows(() => { df.formatRange( assertDoesNotThrow(() => { df.formatRange(
" +.123456789012345678901234567890123456789012345678901234567890 ", " +.123456789012345678901234567890123456789012345678901234567890 ",
" -.1234567890123456789012345678901234567890123456789012345678901 ") }, RangeError); " -.1234567890123456789012345678901234567890123456789012345678901 ")});
assertThrows(() => { df.formatRange( assertDoesNotThrow(() => { df.formatRange(
" +.12e3 ", " +.12e2 ") }, RangeError); " +.12e3 ", " +.12e2 ") });
assertThrows(() => { df.formatRange( assertDoesNotThrow(() => { df.formatRange(
" +123 ", " +.12e2 ") }, RangeError); " +123 ", " +.12e2 ") });
assertThrows(() => { df.formatRange( assertDoesNotThrow(() => { df.formatRange(
" -123 ", " -.12e4 ") }, RangeError); " -123 ", " -.12e4 ") });
// 2b. Else if y is negative-infinity, throw a RangeError exception. assertDoesNotThrow(() => { df.formatRange( " 123 ", " -Infinity ")});
assertThrows(() => { df.formatRange( " 123 ", " -Infinity ") }, RangeError); assertDoesNotThrow(() => { df.formatRange( " 123 ", " -0 ")});
// 2c. Else if y is negative-zero and x ≥ 0, throw a RangeError exception.
assertThrows(() => { df.formatRange( " 123 ", " -0 ") }, RangeError);
// other case which won't throw under 2 // other case which won't throw
assertDoesNotThrow(() => { df.formatRange( " 123 ", " Infinity ") }) assertDoesNotThrow(() => { df.formatRange( " 123 ", " Infinity ") })
assertEquals("123–∞", df.formatRange( " 123 ", " Infinity ")); assertEquals("123–∞", df.formatRange( " 123 ", " Infinity "));
assertDoesNotThrow(() => { df.formatRange( assertDoesNotThrow(() => { df.formatRange(
...@@ -71,28 +67,21 @@ assertDoesNotThrow(() => { df.formatRange( ...@@ -71,28 +67,21 @@ assertDoesNotThrow(() => { df.formatRange(
assertDoesNotThrow(() => { df.formatRange( assertDoesNotThrow(() => { df.formatRange(
" +12345678901234567890.123456789012345678901234567890123456789000000001e20 ", " +12345678901234567890.123456789012345678901234567890123456789000000001e20 ",
" +1234567890.12345678901234567890123456789012345678901234567890e31 ")}) " +1234567890.12345678901234567890123456789012345678901234567890e31 ")})
// 3. Else if x is positive-infinity, then assertDoesNotThrow(() => { df.formatRange( " Infinity ", " 123 ")});
// 3a. If y is a mathematical value, throw a RangeError exception. assertDoesNotThrow(() => { df.formatRange( " +Infinity ", " 123 ")});
assertThrows(() => { df.formatRange( " Infinity ", " 123 ") }, RangeError); assertDoesNotThrow(() => { df.formatRange( " Infinity ", " -Infinity ")});
assertThrows(() => { df.formatRange( " +Infinity ", " 123 ") }, RangeError); assertDoesNotThrow(() => { df.formatRange( " +Infinity ", " -Infinity ")});
// 3b. Else if y is negative-infinity, throw a RangeError exception. assertDoesNotThrow(() => { df.formatRange( " Infinity ", " -0 ")});
assertThrows(() => { df.formatRange( " Infinity ", " -Infinity ") }, RangeError); assertDoesNotThrow(() => { df.formatRange( " +Infinity ", " -0 ")});
assertThrows(() => { df.formatRange( " +Infinity ", " -Infinity ") }, RangeError);
// 3c. Else if y is negative-zero, throw a RangeError exception.
assertThrows(() => { df.formatRange( " Infinity ", " -0 ") }, RangeError);
assertThrows(() => { df.formatRange( " +Infinity ", " -0 ") }, RangeError);
// other case which won't throw under 3 // other case which won't throw under 3
assertDoesNotThrow(() => { df.formatRange( " Infinity ", " Infinity ") }) assertDoesNotThrow(() => { df.formatRange( " Infinity ", " Infinity ") })
assertEquals("~∞", df.formatRange(" Infinity ", " Infinity ")); assertEquals("~∞", df.formatRange(" Infinity ", " Infinity "));
// 4. Else if x is negative-zero, then assertDoesNotThrow(() => { df.formatRange( " -0 ", " -1e-30 ")});
// 4a. If y is a mathematical value and y < 0, throw a RangeError exception. assertDoesNotThrow(() => { df.formatRange( " -0.000e200 ", " -1e-30 ")});
assertThrows(() => { df.formatRange( " -0 ", " -1e-30 ") }, RangeError); assertDoesNotThrow(() => { df.formatRange( " -0 ", " -Infinity ")});
assertThrows(() => { df.formatRange( " -0.000e200 ", " -1e-30 ") }, RangeError); // other case which won't throw
// 4b. Else if y is negative-infinity, throw a RangeError exception.
assertThrows(() => { df.formatRange( " -0 ", " -Infinity ") }, RangeError);
// other case which won't throw under 4
assertDoesNotThrow(() => { df.formatRange( " -0 ", " Infinity ") }) assertDoesNotThrow(() => { df.formatRange( " -0 ", " Infinity ") })
assertEquals("-0 – ∞", df.formatRange(" -0 ", " Infinity ")); assertEquals("-0 – ∞", df.formatRange(" -0 ", " Infinity "));
assertDoesNotThrow(() => { df.formatRange( " -0 ", " -0 ") }) assertDoesNotThrow(() => { df.formatRange( " -0 ", " -0 ") })
......
...@@ -50,18 +50,16 @@ const nf = new Intl.NumberFormat("en", {signDisplay: "exceptZero"}); ...@@ -50,18 +50,16 @@ const nf = new Intl.NumberFormat("en", {signDisplay: "exceptZero"});
// 6. If ... y is NaN, throw a RangeError exception. // 6. If ... y is NaN, throw a RangeError exception.
assertThrows(() => { nf[method](12, NaN) }, RangeError); assertThrows(() => { nf[method](12, NaN) }, RangeError);
// 8. If x is greater than y, throw a RangeError exception. assertDoesNotThrow(() => { nf[method](23, 12)});
// neither x nor y are bigint.
assertThrows(() => { nf[method](23, 12) }, RangeError);
assertDoesNotThrow(() => nf[method](12, 23)); assertDoesNotThrow(() => nf[method](12, 23));
// x is not bigint but y is. // x is not bigint but y is.
assertThrows(() => { nf[method](23, 12n) }, RangeError); assertDoesNotThrow(() => { nf[method](23, 12n)});
assertDoesNotThrow(() => nf[method](12, 23n)); assertDoesNotThrow(() => nf[method](12, 23n));
// x is bigint but y is not. // x is bigint but y is not.
assertThrows(() => { nf[method](23n, 12) }, RangeError); assertDoesNotThrow(() => { nf[method](23n, 12)});
assertDoesNotThrow(() => nf[method](12n, 23)); assertDoesNotThrow(() => nf[method](12n, 23));
// both x and y are bigint. // both x and y are bigint.
assertThrows(() => { nf[method](23n, 12n) }, RangeError); assertDoesNotThrow(() => { nf[method](23n, 12n)});
assertDoesNotThrow(() => nf[method](12n, 23n)); assertDoesNotThrow(() => nf[method](12n, 23n));
validRanges.forEach( validRanges.forEach(
......
...@@ -1020,6 +1020,11 @@ ...@@ -1020,6 +1020,11 @@
# https://github.com/tc39/test262/pull/3603 # https://github.com/tc39/test262/pull/3603
'intl402/NumberFormat/test-option-useGrouping': [FAIL], 'intl402/NumberFormat/test-option-useGrouping': [FAIL],
# https://github.com/tc39/test262/pull/3608
'intl402/NumberFormat/prototype/formatRangeToParts/x-greater-than-y-throws': [FAIL],
'intl402/NumberFormat/prototype/formatRange/x-greater-than-y-throws': [FAIL],
'intl402/PluralRules/prototype/selectRange/x-greater-than-y-throws': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=12763 # https://bugs.chromium.org/p/v8/issues/detail?id=12763
'language/expressions/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier': [FAIL], 'language/expressions/class/decorator/syntax/class-valid/decorator-member-expr-private-identifier': [FAIL],
'language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference': [FAIL], 'language/expressions/class/decorator/syntax/valid/decorator-call-expr-identifier-reference': [FAIL],
......
...@@ -418,11 +418,6 @@ TEST_F(IntlTest, IntlMathematicalValueFromString) { ...@@ -418,11 +418,6 @@ TEST_F(IntlTest, IntlMathematicalValueFromString) {
i_isolate()->factory()->NewStringFromAsciiChecked(cas.string)) i_isolate()->factory()->NewStringFromAsciiChecked(cas.string))
.ToChecked(); .ToChecked();
CHECK_EQ(x.IsNaN(), cas.is_nan); CHECK_EQ(x.IsNaN(), cas.is_nan);
CHECK_EQ(x.IsMinusZero(), cas.is_minus_zero);
CHECK_EQ(x.IsNegative(), cas.is_negative);
CHECK_EQ(x.IsNegativeInfinity(), cas.is_negative_infinity);
CHECK_EQ(x.IsPositiveInfinity(), cas.is_positive_infinity);
CHECK_EQ(x.IsMathematicalValue(), cas.is_mathematical_value);
} }
} }
...@@ -446,66 +441,6 @@ TEST_F(IntlTest, IntlMathematicalValueFromBigInt) { ...@@ -446,66 +441,6 @@ TEST_F(IntlTest, IntlMathematicalValueFromBigInt) {
i_isolate(), BigInt::FromObject(i_isolate(), str).ToHandleChecked()) i_isolate(), BigInt::FromObject(i_isolate(), str).ToHandleChecked())
.ToChecked(); .ToChecked();
CHECK_EQ(x.IsNaN(), false); CHECK_EQ(x.IsNaN(), false);
CHECK_EQ(x.IsMinusZero(), false);
CHECK_EQ(x.IsNegative(), cas.is_negative);
CHECK_EQ(x.IsNegativeInfinity(), false);
CHECK_EQ(x.IsPositiveInfinity(), false);
CHECK_EQ(x.IsMathematicalValue(), true);
}
}
TEST_F(IntlTest, IntlMathematicalValueLessThanString) {
struct TestCase {
const char* x;
const char* y;
bool is_x_less_than_y;
} cases[] = {
{" 1 ", " 2", true},
{" 1 ", " 2 ", true},
{" 1e-1 ", " 2 ", true},
{" 1e1 ", " 2 ", false},
{" 1 ", " 20e-3", false},
{" -1e10 ", " -1e9 ", true},
{" -1e-10 ", " -1e-9 ", false},
{" 123456789012345678901234567890 ", " 123456789012345678901234567890 ",
false},
{" .123456789012345678901234567890 ", " .123456789012345678901234567890 ",
false},
{" .123456789012345678901234567890000 ",
" .12345678901234567890123456789 ", false},
{" .12345678901234567890123456789 ",
" .123456789012345678901234567890000 ", false},
{" 123456789012345678901234567890 ", " 1234567890123456789012345678901 ",
true},
{" 1234567890123456789012345678902 ", " 1234567890123456789012345678901 ",
false},
{" 123456789012345.678901234567890e33 ",
" 12345678901234.5678901234567890e34 ", false},
{" 123456789012345.678901234567890e33 ",
" 12345678901234.5678901234567890e35 ", true},
{" 12345678901234.5678901234567890e34 ",
" 123456789012345.678901234567890e33 ", false},
{" 123456789012345678.901234567890e30 ",
" 12345678901234.5678901234567890e35 ", true},
{" .12345678901234567890123456789 ",
" .1234567890123456789012345678900000001 ", true},
{" -.1234567890123456789012345678900000001 ",
" -.123456789012345678901234567890000 ", true},
{" -.1234567890123456789012345678900000001 ",
" -0.00000123456789012345678901234567890000e5 ", true},
};
for (auto& cas : cases) {
IntlMathematicalValue x =
IntlMathematicalValue::From(
i_isolate(),
i_isolate()->factory()->NewStringFromAsciiChecked(cas.x))
.ToChecked();
IntlMathematicalValue y =
IntlMathematicalValue::From(
i_isolate(),
i_isolate()->factory()->NewStringFromAsciiChecked(cas.y))
.ToChecked();
CHECK_EQ(x.IsLessThan(i_isolate(), y), cas.is_x_less_than_y);
} }
} }
......
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