Bug 1705363 - Fixes to intl::NumberFormatterSkeleton; r=gregtatum

These are fixes for issues noticed with NumberFormatterSkeleton while testing
this code in SpiderMonkey against the full set of intl tests there. I've added
minimal test cases for the issues encountered as part of this patch.

Differential Revision: https://phabricator.services.mozilla.com/D112240
This commit is contained in:
Dan Minor 2021-04-20 18:16:24 +00:00
parent e5512a23ac
commit 28196b0645
3 changed files with 41 additions and 7 deletions

View File

@ -77,6 +77,22 @@ TEST(IntlNumberFormat, Numbers)
ASSERT_EQ(std::u16string_view(res), u"123.456,789");
}
TEST(IntlNumberFormat, SignificantDigits)
{
NumberFormatOptions options;
options.mSignificantDigits = Some(std::make_pair(3, 5));
NumberFormat nf("es-ES", options);
Buffer<uint8_t> buf8;
ASSERT_TRUE(nf.format(123456.789, buf8));
ASSERT_EQ(
std::string_view(static_cast<const char*>(buf8.data()), buf8.mWritten),
"123.460");
ASSERT_TRUE(nf.format(0.7, buf8));
ASSERT_EQ(
std::string_view(static_cast<const char*>(buf8.data()), buf8.mWritten),
"0,700");
}
TEST(IntlNumberFormat, Currency)
{
NumberFormatOptions options;
@ -117,6 +133,23 @@ TEST(IntlNumberFormat, Unit)
const char16_t* res = nf.format(12.34);
ASSERT_TRUE(res != nullptr);
ASSERT_EQ(std::u16string_view(res), u"12.34 metros por segundo");
// Create a string view into a longer string and make sure everything works
// correctly.
const char* unit = "meter-per-second-with-some-trailing-garbage";
options.mUnit = Some(std::make_pair(std::string_view(unit, 5),
NumberFormatOptions::UnitDisplay::Long));
NumberFormat nf2("es-MX", options);
res = nf2.format(12.34);
ASSERT_TRUE(res != nullptr);
ASSERT_EQ(std::u16string_view(res), u"12.34 metros");
options.mUnit = Some(std::make_pair(std::string_view(unit, 16),
NumberFormatOptions::UnitDisplay::Long));
NumberFormat nf3("es-MX", options);
res = nf3.format(12.34);
ASSERT_TRUE(res != nullptr);
ASSERT_EQ(std::u16string_view(res), u"12.34 metros por segundo");
}
} // namespace intl

View File

@ -42,8 +42,8 @@ NumberFormatterSkeleton::NumberFormatterSkeleton(
}
if (options.mSignificantDigits.isSome()) {
if (!fractionDigits(options.mSignificantDigits->first,
options.mSignificantDigits->second)) {
if (!significantDigits(options.mSignificantDigits->first,
options.mSignificantDigits->second)) {
return;
}
}
@ -135,17 +135,19 @@ bool NumberFormatterSkeleton::unit(std::string_view unit) {
// |unit| can be a compound unit identifier, separated by "-per-".
static constexpr char separator[] = "-per-";
size_t separator_len = strlen(separator);
size_t offset = unit.find(separator);
if (offset != std::string_view::npos) {
const auto& numerator = FindSimpleMeasureUnit(unit.substr(0, offset));
const auto& denominator =
FindSimpleMeasureUnit(unit.data() + offset + strlen(separator));
const auto& denominator = FindSimpleMeasureUnit(
std::string_view(unit.data() + offset + separator_len,
unit.length() - offset - separator_len));
return append(u"measure-unit/") && appendUnit(numerator) && append(' ') &&
append(u"per-measure-unit/") && appendUnit(denominator) &&
append(' ');
}
const auto& simple = FindSimpleMeasureUnit(unit.data());
const auto& simple = FindSimpleMeasureUnit(unit);
return append(u"measure-unit/") && appendUnit(simple) && append(' ');
}

View File

@ -4,14 +4,13 @@
#ifndef intl_components_NumberFormatterSkeleton_h_
#define intl_components_NumberFormatterSkeleton_h_
#include <string_view>
#include "mozilla/intl/NumberFormat.h"
#include "mozilla/Vector.h"
#include "unicode/unumberformatter.h"
namespace mozilla {
namespace intl {
struct NumberFormatOptions;
/**
* Class to create a number formatter skeleton.
*