tor-browser

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

testNumberToString.cpp (4220B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 */
      4 /* This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 #include "mozilla/FloatingPoint.h"  // mozilla::{PositiveInfinity,UnspecifiedNaN}
      9 
     10 #include <stddef.h>  // size_t
     11 #include <string.h>  // memcmp, memset
     12 
     13 #include "js/Conversions.h"  // JS::NumberToString, JS::MaximumNumberToStringLength
     14 #include "jsapi-tests/tests.h"  // BEGIN_TEST, CHECK_EQUAL, END_TEST
     15 #include "util/Text.h"          // js_strlen
     16 
     17 #define REST(x) x, (js_strlen(x)), __LINE__
     18 
     19 static const struct NumberToStringTest {
     20  double number;
     21  const char* expected;
     22  size_t expectedLength;
     23  size_t lineno;
     24 } numberToStringTests[] = {
     25    {5e-324, REST("5e-324")},                          // 2**-1074
     26    {9.5367431640625e-7, REST("9.5367431640625e-7")},  // 2**-20
     27    {0.0000010984284297360395, REST("0.0000010984284297360395")},
     28    {0.0000019073486328125, REST("0.0000019073486328125")},  // 2**-19
     29    {0.000003814697265625, REST("0.000003814697265625")},    // 2**-18
     30    {0.0000057220458984375, REST("0.0000057220458984375")},  // 2**-18 + 2**-19
     31    {0.000244140625, REST("0.000244140625")},                // 2**-12
     32    {0.125, REST("0.125")},
     33    {0.25, REST("0.25")},
     34    {0.5, REST("0.5")},
     35    {1, REST("1")},
     36    {1.5, REST("1.5")},
     37    {2, REST("2")},
     38    {9, REST("9")},
     39    {10, REST("10")},
     40    {15, REST("15")},
     41    {16, REST("16")},
     42    {389427, REST("389427")},
     43    {1073741823, REST("1073741823")},
     44    {1073741824, REST("1073741824")},
     45    {1073741825, REST("1073741825")},
     46    {2147483647, REST("2147483647")},
     47    {2147483648, REST("2147483648")},
     48    {2147483649, REST("2147483649")},
     49    {4294967294, REST("4294967294")},
     50    {4294967295, REST("4294967295")},
     51    {4294967296, REST("4294967296")},
     52    {999999999999999900000.0, REST("999999999999999900000")},
     53    {999999999999999900000.0 + 65535, REST("999999999999999900000")},
     54    {999999999999999900000.0 + 65536, REST("1e+21")},
     55    {1.7976931348623157e+308, REST("1.7976931348623157e+308")},  // MAX_VALUE
     56 };
     57 
     58 static constexpr char PoisonChar = 0x37;
     59 
     60 struct StorageForNumberToString {
     61  char out[JS::MaximumNumberToStringLength];
     62  char overflow;
     63 } storage;
     64 
     65 BEGIN_TEST(testNumberToString) {
     66  StorageForNumberToString storage;
     67 
     68  if (!testNormalValues(false, storage)) {
     69    return false;
     70  }
     71 
     72  if (!testNormalValues(true, storage)) {
     73    return false;
     74  }
     75 
     76  NumberToStringTest zeroTest = {0.0, REST("0")};
     77  if (!testOne(zeroTest, false, storage)) {
     78    return false;
     79  }
     80  NumberToStringTest negativeZeroTest = {-0.0, REST("0")};
     81  if (!testOne(negativeZeroTest, false, storage)) {
     82    return false;
     83  }
     84 
     85  NumberToStringTest infTest = {mozilla::PositiveInfinity<double>(),
     86                                REST("Infinity")};
     87  if (!testOne(infTest, false, storage)) {
     88    return false;
     89  }
     90  if (!testOne(infTest, true, storage)) {
     91    return false;
     92  }
     93 
     94  NumberToStringTest nanTest = {mozilla::UnspecifiedNaN<double>(), REST("NaN")};
     95  return testOne(nanTest, false, storage);
     96 }
     97 
     98 bool testNormalValues(bool hasMinusSign, StorageForNumberToString& storage) {
     99  for (const auto& test : numberToStringTests) {
    100    if (!testOne(test, hasMinusSign, storage)) {
    101      return false;
    102    }
    103  }
    104 
    105  return true;
    106 }
    107 
    108 bool testOne(const NumberToStringTest& test, bool hasMinusSign,
    109             StorageForNumberToString& storage) {
    110  memset(&storage, PoisonChar, sizeof(storage));
    111 
    112  JS::NumberToString(hasMinusSign ? -test.number : test.number, storage.out);
    113 
    114  CHECK_EQUAL(storage.overflow, PoisonChar);
    115 
    116  const char* start = storage.out;
    117  if (hasMinusSign) {
    118    CHECK_EQUAL(start[0], '-');
    119    start++;
    120  }
    121 
    122  if (!checkEqual(memcmp(start, test.expected, test.expectedLength), 0, start,
    123                  test.expected, __FILE__, test.lineno)) {
    124    return false;
    125  }
    126 
    127  char actualTerminator[] = {start[test.expectedLength], '\0'};
    128  return checkEqual(actualTerminator[0], '\0', actualTerminator, "'\\0'",
    129                    __FILE__, test.lineno);
    130 }
    131 END_TEST(testNumberToString)
    132 
    133 #undef REST