tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestNumberFormat.cpp (8299B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 #include "gtest/gtest.h"
      5 
      6 #include "mozilla/intl/NumberFormat.h"
      7 #include "TestBuffer.h"
      8 
      9 #include <string_view>
     10 
     11 namespace mozilla {
     12 namespace intl {
     13 
     14 TEST(IntlNumberFormat, Basic)
     15 {
     16  NumberFormatOptions options;
     17  UniquePtr<NumberFormat> nf =
     18      NumberFormat::TryCreate("en-US", options).unwrap();
     19  TestBuffer<char> buf8;
     20  ASSERT_TRUE(nf->format(1234.56, buf8).isOk());
     21  ASSERT_EQ(buf8.get_string_view(), "1,234.56");
     22  TestBuffer<char16_t> buf16;
     23  ASSERT_TRUE(nf->format(1234.56, buf16).isOk());
     24  ASSERT_EQ(buf16.get_string_view(), u"1,234.56");
     25  const char16_t* res16 = nf->format(1234.56).unwrap().data();
     26  ASSERT_TRUE(res16 != nullptr);
     27  ASSERT_EQ(std::u16string_view(res16), u"1,234.56");
     28 
     29  UniquePtr<NumberFormat> nfAr =
     30      NumberFormat::TryCreate("ar-EG", options).unwrap();
     31  ASSERT_TRUE(nfAr->format(1234.56, buf8).isOk());
     32  ASSERT_EQ(buf8.get_string_view(), "١٬٢٣٤٫٥٦");
     33  ASSERT_TRUE(nfAr->format(1234.56, buf16).isOk());
     34  ASSERT_EQ(buf16.get_string_view(), u"١٬٢٣٤٫٥٦");
     35  res16 = nfAr->format(1234.56).unwrap().data();
     36  ASSERT_TRUE(res16 != nullptr);
     37  ASSERT_EQ(std::u16string_view(res16), u"١٬٢٣٤٫٥٦");
     38 }
     39 
     40 TEST(IntlNumberFormat, Numbers)
     41 {
     42  NumberFormatOptions options;
     43  UniquePtr<NumberFormat> nf =
     44      NumberFormat::TryCreate("es-ES", options).unwrap();
     45  TestBuffer<char> buf8;
     46  ASSERT_TRUE(nf->format(123456.789, buf8).isOk());
     47  ASSERT_EQ(buf8.get_string_view(), "123.456,789");
     48  TestBuffer<char16_t> buf16;
     49  ASSERT_TRUE(nf->format(123456.789, buf16).isOk());
     50  ASSERT_EQ(buf16.get_string_view(), u"123.456,789");
     51 
     52  const char16_t* res = nf->format(123456.789).unwrap().data();
     53  ASSERT_TRUE(res != nullptr);
     54  ASSERT_EQ(std::u16string_view(res), u"123.456,789");
     55 }
     56 
     57 TEST(IntlNumberFormat, SignificantDigits)
     58 {
     59  NumberFormatOptions options;
     60  options.mSignificantDigits = Some(std::make_pair(3, 5));
     61  UniquePtr<NumberFormat> nf =
     62      NumberFormat::TryCreate("es-ES", options).unwrap();
     63  TestBuffer<char> buf8;
     64  ASSERT_TRUE(nf->format(123456.789, buf8).isOk());
     65  ASSERT_EQ(buf8.get_string_view(), "123.460");
     66  ASSERT_TRUE(nf->format(0.7, buf8).isOk());
     67  ASSERT_EQ(buf8.get_string_view(), "0,700");
     68 }
     69 
     70 TEST(IntlNumberFormat, Currency)
     71 {
     72  NumberFormatOptions options;
     73  options.mCurrency =
     74      Some(std::make_pair("MXN", NumberFormatOptions::CurrencyDisplay::Symbol));
     75  UniquePtr<NumberFormat> nf =
     76      NumberFormat::TryCreate("es-MX", options).unwrap();
     77  TestBuffer<char> buf8;
     78  ASSERT_TRUE(nf->format(123456.789, buf8).isOk());
     79  ASSERT_EQ(buf8.get_string_view(), "$123,456.79");
     80  TestBuffer<char16_t> buf16;
     81  ASSERT_TRUE(nf->format(123456.789, buf16).isOk());
     82  ASSERT_EQ(buf16.get_string_view(), u"$123,456.79");
     83  const char16_t* res = nf->format(123456.789).unwrap().data();
     84  ASSERT_TRUE(res != nullptr);
     85  ASSERT_EQ(std::u16string_view(res), u"$123,456.79");
     86 }
     87 
     88 TEST(IntlNumberFormat, Unit)
     89 {
     90  NumberFormatOptions options;
     91  options.mUnit = Some(std::make_pair("meter-per-second",
     92                                      NumberFormatOptions::UnitDisplay::Long));
     93  UniquePtr<NumberFormat> nf =
     94      NumberFormat::TryCreate("es-MX", options).unwrap();
     95  TestBuffer<char> buf8;
     96  ASSERT_TRUE(nf->format(12.34, buf8).isOk());
     97  ASSERT_EQ(buf8.get_string_view(), "12.34 metros por segundo");
     98  TestBuffer<char16_t> buf16;
     99  ASSERT_TRUE(nf->format(12.34, buf16).isOk());
    100  ASSERT_EQ(buf16.get_string_view(), u"12.34 metros por segundo");
    101  const char16_t* res = nf->format(12.34).unwrap().data();
    102  ASSERT_TRUE(res != nullptr);
    103  ASSERT_EQ(std::u16string_view(res), u"12.34 metros por segundo");
    104 
    105  // Create a string view into a longer string and make sure everything works
    106  // correctly.
    107  const char* unit = "meter-per-second-with-some-trailing-garbage";
    108  options.mUnit = Some(std::make_pair(std::string_view(unit, 5),
    109                                      NumberFormatOptions::UnitDisplay::Long));
    110  UniquePtr<NumberFormat> nf2 =
    111      NumberFormat::TryCreate("es-MX", options).unwrap();
    112  res = nf2->format(12.34).unwrap().data();
    113  ASSERT_TRUE(res != nullptr);
    114  ASSERT_EQ(std::u16string_view(res), u"12.34 metros");
    115 
    116  options.mUnit = Some(std::make_pair(std::string_view(unit, 16),
    117                                      NumberFormatOptions::UnitDisplay::Long));
    118  UniquePtr<NumberFormat> nf3 =
    119      NumberFormat::TryCreate("es-MX", options).unwrap();
    120  res = nf3->format(12.34).unwrap().data();
    121  ASSERT_TRUE(res != nullptr);
    122  ASSERT_EQ(std::u16string_view(res), u"12.34 metros por segundo");
    123 }
    124 
    125 TEST(IntlNumberFormat, RoundingMode)
    126 {
    127  NumberFormatOptions options;
    128  options.mFractionDigits = Some(std::make_pair(0, 2));
    129  options.mStripTrailingZero = true;
    130  options.mRoundingIncrement = 5;
    131  options.mRoundingMode = NumberFormatOptions::RoundingMode::Ceil;
    132 
    133  UniquePtr<NumberFormat> nf = NumberFormat::TryCreate("en", options).unwrap();
    134 
    135  const char16_t* res16 = nf->format(1.92).unwrap().data();
    136  ASSERT_TRUE(res16 != nullptr);
    137  ASSERT_EQ(std::u16string_view(res16), u"1.95");
    138 
    139  res16 = nf->format(1.96).unwrap().data();
    140  ASSERT_TRUE(res16 != nullptr);
    141  ASSERT_EQ(std::u16string_view(res16), u"2");
    142 }
    143 
    144 TEST(IntlNumberFormat, Grouping)
    145 {
    146  NumberFormatOptions options;
    147  options.mGrouping = NumberFormatOptions::Grouping::Min2;
    148 
    149  UniquePtr<NumberFormat> nf = NumberFormat::TryCreate("en", options).unwrap();
    150 
    151  const char16_t* res16 = nf->format(1'000.0).unwrap().data();
    152  ASSERT_TRUE(res16 != nullptr);
    153  ASSERT_EQ(std::u16string_view(res16), u"1000");
    154 
    155  res16 = nf->format(10'000.0).unwrap().data();
    156  ASSERT_TRUE(res16 != nullptr);
    157  ASSERT_EQ(std::u16string_view(res16), u"10,000");
    158 }
    159 
    160 TEST(IntlNumberFormat, RoundingPriority)
    161 {
    162  NumberFormatOptions options;
    163  options.mFractionDigits = Some(std::make_pair(2, 2));
    164  options.mSignificantDigits = Some(std::make_pair(1, 2));
    165  options.mRoundingPriority =
    166      NumberFormatOptions::RoundingPriority::LessPrecision;
    167 
    168  UniquePtr<NumberFormat> nf1 = NumberFormat::TryCreate("en", options).unwrap();
    169 
    170  const char16_t* res16 = nf1->format(4.321).unwrap().data();
    171  ASSERT_TRUE(res16 != nullptr);
    172  ASSERT_EQ(std::u16string_view(res16), u"4.3");
    173 
    174  options.mRoundingPriority =
    175      NumberFormatOptions::RoundingPriority::MorePrecision;
    176 
    177  UniquePtr<NumberFormat> nf2 = NumberFormat::TryCreate("en", options).unwrap();
    178 
    179  res16 = nf2->format(4.321).unwrap().data();
    180  ASSERT_TRUE(res16 != nullptr);
    181  ASSERT_EQ(std::u16string_view(res16), u"4.32");
    182 }
    183 
    184 TEST(IntlNumberFormat, FormatToParts)
    185 {
    186  NumberFormatOptions options;
    187  UniquePtr<NumberFormat> nf =
    188      NumberFormat::TryCreate("es-ES", options).unwrap();
    189  NumberPartVector parts;
    190  const char16_t* res = nf->formatToParts(123456.789, parts).unwrap().data();
    191  ASSERT_TRUE(res != nullptr);
    192  ASSERT_EQ(std::u16string_view(res), u"123.456,789");
    193  ASSERT_EQ(parts.length(), 5U);
    194 
    195  // NumberFormat only ever produces number parts with NumberPartSource::Shared.
    196 
    197  ASSERT_EQ(parts[0],
    198            (NumberPart{NumberPartType::Integer, NumberPartSource::Shared, 3}));
    199  ASSERT_EQ(parts[1],
    200            (NumberPart{NumberPartType::Group, NumberPartSource::Shared, 4}));
    201  ASSERT_EQ(parts[2],
    202            (NumberPart{NumberPartType::Integer, NumberPartSource::Shared, 7}));
    203  ASSERT_EQ(parts[3],
    204            (NumberPart{NumberPartType::Decimal, NumberPartSource::Shared, 8}));
    205  ASSERT_EQ(parts[4], (NumberPart{NumberPartType::Fraction,
    206                                  NumberPartSource::Shared, 11}));
    207 }
    208 
    209 TEST(IntlNumberFormat, GetAvailableLocales)
    210 {
    211  using namespace std::literals;
    212 
    213  int32_t english = 0;
    214  int32_t german = 0;
    215  int32_t chinese = 0;
    216 
    217  // Since this list is dependent on ICU, and may change between upgrades, only
    218  // test a subset of the available locales.
    219  for (const char* locale : NumberFormat::GetAvailableLocales()) {
    220    if (locale == "en"sv) {
    221      english++;
    222    } else if (locale == "de"sv) {
    223      german++;
    224    } else if (locale == "zh"sv) {
    225      chinese++;
    226    }
    227  }
    228 
    229  // Each locale should be found exactly once.
    230  ASSERT_EQ(english, 1);
    231  ASSERT_EQ(german, 1);
    232  ASSERT_EQ(chinese, 1);
    233 }
    234 
    235 }  // namespace intl
    236 }  // namespace mozilla