LCOV - code coverage report
Current view: top level - tests - catch_string.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 541 542 99.8 %
Date: 2023-12-10 17:25:12 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2011-2023  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/as2js
       4             : // contact@m2osw.com
       5             : //
       6             : // This program is free software: you can redistribute it and/or modify
       7             : // it under the terms of the GNU General Public License as published by
       8             : // the Free Software Foundation, either version 3 of the License, or
       9             : // (at your option) any later version.
      10             : //
      11             : // This program is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : //
      16             : // You should have received a copy of the GNU General Public License
      17             : // along with this program.  If not, see <https://www.gnu.org/licenses/>.
      18             : 
      19             : // as2js
      20             : //
      21             : #include    <as2js/string.h>
      22             : #include    <as2js/exception.h>
      23             : 
      24             : 
      25             : // self
      26             : //
      27             : #include    "catch_main.h"
      28             : 
      29             : 
      30             : // C++
      31             : //
      32             : #include    <algorithm>
      33             : #include    <cstring>
      34             : #include    <iomanip>
      35             : 
      36             : 
      37             : // last include
      38             : //
      39             : #include    <snapdev/poison.h>
      40             : 
      41             : 
      42             : 
      43             : namespace
      44             : {
      45             : 
      46             : 
      47             : 
      48       10051 : bool close_double(double a, double b, double epsilon)
      49             : {
      50       10051 :     return a >= b - epsilon && a <= b + epsilon;
      51             : }
      52             : 
      53             : 
      54             : 
      55             : }
      56             : // no name namespace
      57             : 
      58             : 
      59             : 
      60             : 
      61           1 : CATCH_TEST_CASE("string_empty", "[string][type]")
      62             : {
      63           1 :     CATCH_START_SECTION("string: empty string validity")
      64             :     {
      65             :         // a little extra test, make sure a string is empty on
      66             :         // creation without anything
      67             :         //
      68           1 :         std::string str1;
      69           1 :         CATCH_REQUIRE(as2js::valid(str1));
      70           1 :     }
      71           1 :     CATCH_END_SECTION()
      72           1 : }
      73             : 
      74             : 
      75           1 : CATCH_TEST_CASE("string_bad_utf8", "[string][type]")
      76             : {
      77           1 :     CATCH_START_SECTION("string: bad UTF-8 sequences")
      78             :     {
      79             :         // UTF-8 starts with 0xC0 to 0xF4 and those must be followed by
      80             :         // 0x80 to 0xBF bytes anything else is incorrect
      81             :         //
      82          54 :         for(int i(0xC0); i <= 0xF4; ++i)
      83             :         {
      84             :             // too small a number just after 0xA0 to 0xF4
      85             :             //
      86        6784 :             for(int j(0x01); j <= 0x7F; ++j)
      87             :             {
      88        6731 :                 char const buf[3]{
      89             :                     static_cast<char>(i),
      90             :                     static_cast<char>(j),
      91             :                     '\0'
      92        6731 :                 };
      93       13462 :                 std::string const bad_utf8(buf);
      94        6731 :                 CATCH_REQUIRE_FALSE(as2js::valid(bad_utf8));
      95             : 
      96        6731 :                 std::string const start_string(SNAP_CATCH2_NAMESPACE::random_string(1, 100, SNAP_CATCH2_NAMESPACE::character_t::CHARACTER_ASCII));
      97        6731 :                 std::string const end_string(SNAP_CATCH2_NAMESPACE::random_string(1, 100, SNAP_CATCH2_NAMESPACE::character_t::CHARACTER_ASCII));
      98        6731 :                 CATCH_REQUIRE(as2js::valid(start_string));
      99        6731 :                 CATCH_REQUIRE(as2js::valid(end_string));
     100             : 
     101             :                 // make sure it gets caught anywhere in a string
     102             :                 //
     103       13462 :                 std::string const complete_string(start_string + bad_utf8 + end_string);
     104        6731 :                 CATCH_REQUIRE_FALSE(as2js::valid(complete_string));
     105        6731 :             }
     106             : 
     107             :             // too large a number just after 0xA0 to 0xFF
     108             :             //
     109        3445 :             for(int j(0xC0); j <= 0xFF; ++j)
     110             :             {
     111        3392 :                 char buf[3]{
     112             :                     static_cast<char>(i),
     113             :                     static_cast<char>(j),
     114             :                     '\0'
     115        3392 :                 };
     116        6784 :                 std::string const bad_utf8(buf);
     117        3392 :                 CATCH_REQUIRE_FALSE(as2js::valid(bad_utf8));
     118             : 
     119        3392 :                 std::string const start_string(SNAP_CATCH2_NAMESPACE::random_string(1, 100, SNAP_CATCH2_NAMESPACE::character_t::CHARACTER_ASCII));
     120        3392 :                 std::string const end_string(SNAP_CATCH2_NAMESPACE::random_string(1, 100, SNAP_CATCH2_NAMESPACE::character_t::CHARACTER_ASCII));
     121        3392 :                 CATCH_REQUIRE(as2js::valid(start_string));
     122        3392 :                 CATCH_REQUIRE(as2js::valid(end_string));
     123             : 
     124             :                 // make sure it gets caught anywhere in a string
     125             :                 //
     126        6784 :                 std::string const complete_string(start_string + bad_utf8 + end_string);
     127        3392 :                 CATCH_REQUIRE_FALSE(as2js::valid(complete_string));
     128        3392 :             }
     129             : 
     130             :             // note: the libutf8 already has many tests so I won't check
     131             :             //       every single possibility of invalid UTF-8; if there is
     132             :             //       an issue with such, we should verify with libutf8 instead
     133             :         }
     134             :     }
     135           1 :     CATCH_END_SECTION()
     136           1 : }
     137             : 
     138             : 
     139           3 : CATCH_TEST_CASE("string", "[string][type]")
     140             : {
     141           3 :     CATCH_START_SECTION("string: check valid characters")
     142             :     {
     143     1112065 :         for(char32_t c(0); c < 0x110000; ++c)
     144             :         {
     145             :             // skip the surrogates at once
     146             :             //
     147     1112064 :             if(c == 0xD800)
     148             :             {
     149           1 :                 c = 0xE000;
     150             :             }
     151     1112064 :             CATCH_REQUIRE(as2js::valid_character(c));
     152             :         }
     153             :     }
     154           3 :     CATCH_END_SECTION()
     155             : 
     156           3 :     CATCH_START_SECTION("string: check surrogates (not valid UTF-32)")
     157             :     {
     158        2049 :         for(char32_t c(0xD800); c < 0xE000; ++c)
     159             :         {
     160        2048 :             CATCH_REQUIRE_FALSE(as2js::valid_character(c));
     161             :         }
     162             :     }
     163           3 :     CATCH_END_SECTION()
     164             : 
     165           3 :     CATCH_START_SECTION("string: check outside range (not valid UTF-32)")
     166             :     {
     167        1001 :         for(int i(0); i < 1000; ++i)
     168             :         {
     169        1000 :             char32_t c(0);
     170             :             do
     171             :             {
     172        1000 :                 SNAP_CATCH2_NAMESPACE::random(c);
     173             :             }
     174        1000 :             while(c < 0x110000);
     175        1000 :             CATCH_REQUIRE_FALSE(as2js::valid_character(c));
     176             :         }
     177             :     }
     178           3 :     CATCH_END_SECTION()
     179           3 : }
     180             : 
     181             : 
     182          15 : CATCH_TEST_CASE("string_number", "[string][type][number]")
     183             : {
     184          15 :     CATCH_START_SECTION("string_number: empty string is 0, 0.0, and false")
     185             :     {
     186           1 :         std::string str;
     187           1 :         CATCH_REQUIRE(as2js::is_integer(str));
     188           1 :         CATCH_REQUIRE(as2js::is_floating_point(str));
     189           1 :         CATCH_REQUIRE(as2js::is_number(str));
     190           1 :         CATCH_REQUIRE(as2js::to_integer(str) == 0);
     191             : #pragma GCC diagnostic push
     192             : #pragma GCC diagnostic ignored "-Wfloat-equal"
     193           1 :         bool const is_equal(as2js::to_floating_point(str) == 0.0);
     194             : #pragma GCC diagnostic pop
     195           1 :         CATCH_REQUIRE(is_equal);
     196           1 :         CATCH_REQUIRE_FALSE(as2js::is_true(str));
     197           1 :     }
     198          15 :     CATCH_END_SECTION()
     199             : 
     200          15 :     CATCH_START_SECTION("string_number: a lone sign (+ or -)")
     201             :     {
     202           2 :         std::string str("+");
     203           1 :         CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     204           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     205           1 :         CATCH_REQUIRE_FALSE(as2js::is_number(str));
     206           1 :         CATCH_REQUIRE(as2js::is_true(str));
     207             : 
     208           1 :         str = "-";
     209           1 :         CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     210           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     211           1 :         CATCH_REQUIRE_FALSE(as2js::is_number(str));
     212           1 :         CATCH_REQUIRE(as2js::is_true(str));
     213           1 :     }
     214          15 :     CATCH_END_SECTION()
     215             : 
     216          15 :     CATCH_START_SECTION("string_number: a period alone is not a floating point number")
     217             :     {
     218           2 :         std::string str(".");
     219           1 :         CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     220           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     221           1 :         CATCH_REQUIRE_FALSE(as2js::is_number(str));
     222           1 :         CATCH_REQUIRE(as2js::is_true(str));
     223             : 
     224           1 :         str = "+.";
     225           1 :         CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     226           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     227           1 :         CATCH_REQUIRE_FALSE(as2js::is_number(str));
     228           1 :         CATCH_REQUIRE(as2js::is_true(str));
     229             : 
     230           1 :         str = "-.";
     231           1 :         CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     232           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     233           1 :         CATCH_REQUIRE_FALSE(as2js::is_number(str));
     234           1 :         CATCH_REQUIRE(as2js::is_true(str));
     235             : 
     236           1 :         str = "!.5";
     237           1 :         CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     238           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     239           1 :         CATCH_REQUIRE_FALSE(as2js::is_number(str));
     240           1 :         CATCH_REQUIRE(as2js::is_true(str));
     241           1 :     }
     242          15 :     CATCH_END_SECTION()
     243             : 
     244          15 :     CATCH_START_SECTION("string_number: just one letter, even an hexadecimal letter, fails")
     245             :     {
     246           7 :         for(int c('a'); c <= 'f'; ++c)
     247             :         {
     248          12 :             std::string lower(1, c);
     249           6 :             CATCH_REQUIRE_FALSE(as2js::is_integer(lower));
     250           6 :             CATCH_REQUIRE_FALSE(as2js::is_floating_point(lower));
     251           6 :             CATCH_REQUIRE_FALSE(as2js::is_number(lower));
     252           6 :             CATCH_REQUIRE(as2js::is_true(lower));
     253             : 
     254          12 :             std::string upper(1, c & ~0x20);
     255           6 :             CATCH_REQUIRE_FALSE(as2js::is_integer(upper));
     256           6 :             CATCH_REQUIRE_FALSE(as2js::is_floating_point(upper));
     257           6 :             CATCH_REQUIRE_FALSE(as2js::is_number(upper));
     258           6 :             CATCH_REQUIRE(as2js::is_true(upper));
     259           6 :         }
     260             :     }
     261          15 :     CATCH_END_SECTION()
     262             : 
     263          15 :     CATCH_START_SECTION("string_number: no integral part means not a number (lowercase)")
     264             :     {
     265           2 :         std::string str("xyz");
     266           1 :         CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     267           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     268           1 :         CATCH_REQUIRE_FALSE(as2js::is_number(str));
     269           1 :         CATCH_REQUIRE(as2js::is_true(str));
     270           1 :     }
     271          15 :     CATCH_END_SECTION()
     272             : 
     273          15 :     CATCH_START_SECTION("string_number: no integral part means not a number (uppercase)")
     274             :     {
     275           2 :         std::string str("XYZ");
     276           1 :         CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     277           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     278           1 :         CATCH_REQUIRE_FALSE(as2js::is_number(str));
     279           1 :         CATCH_REQUIRE(as2js::is_true(str));
     280           1 :     }
     281          15 :     CATCH_END_SECTION()
     282             : 
     283          15 :     CATCH_START_SECTION("string_number: an exponent must be followed by a number")
     284             :     {
     285           2 :         std::string str("31.4159e");
     286           1 :         CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     287           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     288           1 :         CATCH_REQUIRE_FALSE(as2js::is_number(str));
     289           1 :         CATCH_REQUIRE(as2js::is_true(str));
     290             : 
     291             :         // adding a sign is not enough
     292             :         //
     293           1 :         str += '+';
     294           1 :         CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     295           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     296           1 :         CATCH_REQUIRE_FALSE(as2js::is_number(str));
     297           1 :         CATCH_REQUIRE(as2js::is_true(str));
     298             : 
     299           1 :         str[str.length() - 1] = '-';
     300           1 :         CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     301           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     302           1 :         CATCH_REQUIRE_FALSE(as2js::is_number(str));
     303           1 :         CATCH_REQUIRE(as2js::is_true(str));
     304           1 :     }
     305          15 :     CATCH_END_SECTION()
     306             : 
     307          15 :     CATCH_START_SECTION("string_number: 0x and 0X are not hexadecimal numbers")
     308             :     {
     309             :         {
     310           2 :             std::string str("0x");
     311           1 :             CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     312           1 :             CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     313           1 :             CATCH_REQUIRE_FALSE(as2js::is_number(str));
     314           1 :             CATCH_REQUIRE_THROWS_MATCHES(
     315             :                       as2js::to_integer(str)
     316             :                     , as2js::internal_error
     317             :                     , Catch::Matchers::ExceptionMessage(
     318             :                               "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     319           1 :             CATCH_REQUIRE(std::isnan(as2js::to_floating_point(str)));
     320           1 :             CATCH_REQUIRE(as2js::is_true(str));
     321           1 :         }
     322             : 
     323             :         {
     324           2 :             std::string str("0X");
     325           1 :             CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     326           1 :             CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     327           1 :             CATCH_REQUIRE_FALSE(as2js::is_number(str));
     328           1 :             CATCH_REQUIRE_THROWS_MATCHES(
     329             :                       as2js::to_integer(str)
     330             :                     , as2js::internal_error
     331             :                     , Catch::Matchers::ExceptionMessage(
     332             :                               "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     333           1 :             CATCH_REQUIRE(std::isnan(as2js::to_floating_point(str)));
     334           1 :             CATCH_REQUIRE(as2js::is_true(str));
     335           1 :         }
     336             :     }
     337          15 :     CATCH_END_SECTION()
     338             : 
     339          15 :     CATCH_START_SECTION("string_number: strings with a <utf-8 char: a+aron> are not numbers")
     340             :     {
     341             :         { // straight UTF-8 char not a digit at all
     342           2 :             std::string str("\xC3\xA5");
     343           1 :             CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     344           1 :             CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     345           1 :             CATCH_REQUIRE_FALSE(as2js::is_number(str));
     346           1 :             CATCH_REQUIRE_THROWS_MATCHES(
     347             :                       as2js::to_integer(str)
     348             :                     , as2js::internal_error
     349             :                     , Catch::Matchers::ExceptionMessage(
     350             :                               "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     351           1 :             CATCH_REQUIRE(std::isnan(as2js::to_floating_point(str)));
     352           1 :             CATCH_REQUIRE(as2js::is_true(str));
     353           1 :         }
     354             : 
     355             :         {
     356           2 :             std::string str("0xABC\xC3\xA5");
     357           1 :             CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     358           1 :             CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     359           1 :             CATCH_REQUIRE_FALSE(as2js::is_number(str));
     360           1 :             CATCH_REQUIRE_THROWS_MATCHES(
     361             :                       as2js::to_integer(str)
     362             :                     , as2js::internal_error
     363             :                     , Catch::Matchers::ExceptionMessage(
     364             :                               "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     365           1 :             CATCH_REQUIRE(std::isnan(as2js::to_floating_point(str)));
     366           1 :             CATCH_REQUIRE(as2js::is_true(str));
     367           1 :         }
     368             :     }
     369          15 :     CATCH_END_SECTION()
     370             : 
     371          15 :     CATCH_START_SECTION("string_number: 0g/0z and 0G/0Z represents nothing useful")
     372             :     {
     373             :         {
     374           2 :             std::string str("0g");
     375           1 :             CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     376           1 :             CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     377           1 :             CATCH_REQUIRE_FALSE(as2js::is_number(str));
     378           1 :             CATCH_REQUIRE_THROWS_MATCHES(
     379             :                       as2js::to_integer(str)
     380             :                     , as2js::internal_error
     381             :                     , Catch::Matchers::ExceptionMessage(
     382             :                               "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     383           1 :             CATCH_REQUIRE(std::isnan(as2js::to_floating_point(str)));
     384           1 :             CATCH_REQUIRE(as2js::is_true(str));
     385           1 :         }
     386             : 
     387             :         {
     388           2 :             std::string str("0z");
     389           1 :             CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     390           1 :             CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     391           1 :             CATCH_REQUIRE_FALSE(as2js::is_number(str));
     392           1 :             CATCH_REQUIRE_THROWS_MATCHES(
     393             :                       as2js::to_integer(str)
     394             :                     , as2js::internal_error
     395             :                     , Catch::Matchers::ExceptionMessage(
     396             :                               "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     397           1 :             CATCH_REQUIRE(std::isnan(as2js::to_floating_point(str)));
     398           1 :             CATCH_REQUIRE(as2js::is_true(str));
     399           1 :         }
     400             : 
     401             :         {
     402           2 :             std::string str("0G");
     403           1 :             CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     404           1 :             CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     405           1 :             CATCH_REQUIRE_FALSE(as2js::is_number(str));
     406           1 :             CATCH_REQUIRE_THROWS_MATCHES(
     407             :                       as2js::to_integer(str)
     408             :                     , as2js::internal_error
     409             :                     , Catch::Matchers::ExceptionMessage(
     410             :                               "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     411           1 :             CATCH_REQUIRE(std::isnan(as2js::to_floating_point(str)));
     412           1 :             CATCH_REQUIRE(as2js::is_true(str));
     413           1 :         }
     414             : 
     415             :         {
     416           2 :             std::string str("0Z");
     417           1 :             CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     418           1 :             CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     419           1 :             CATCH_REQUIRE_FALSE(as2js::is_number(str));
     420           1 :             CATCH_REQUIRE_THROWS_MATCHES(
     421             :                       as2js::to_integer(str)
     422             :                     , as2js::internal_error
     423             :                     , Catch::Matchers::ExceptionMessage(
     424             :                               "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     425           1 :             CATCH_REQUIRE(std::isnan(as2js::to_floating_point(str)));
     426           1 :             CATCH_REQUIRE(as2js::is_true(str));
     427           1 :         }
     428             :     }
     429          15 :     CATCH_END_SECTION()
     430             : 
     431          15 :     CATCH_START_SECTION("string_number: octal is not detected; we have only decimal and hexadecimal")
     432             :     {
     433             :         // octal is not supported here, show that the string is
     434             :         // seen as a decimal number
     435             :         //
     436           2 :         std::string str("071");
     437           1 :         CATCH_REQUIRE(as2js::is_integer(str));
     438           1 :         CATCH_REQUIRE(as2js::is_floating_point(str));
     439           1 :         CATCH_REQUIRE(as2js::is_number(str));
     440           1 :         CATCH_REQUIRE(as2js::to_integer(str) == 71);
     441             : #pragma GCC diagnostic push
     442             : #pragma GCC diagnostic ignored "-Wfloat-equal"
     443           1 :         bool const is_equal(as2js::to_floating_point(str) == 71.0);
     444             : #pragma GCC diagnostic pop
     445           1 :         CATCH_REQUIRE(is_equal);
     446           1 :         CATCH_REQUIRE(as2js::is_true(str));
     447           1 :     }
     448          15 :     CATCH_END_SECTION()
     449             : 
     450          15 :     CATCH_START_SECTION("string_number: integers -100,000 to +100,000")
     451             :     {
     452      200002 :         for(int64_t i(-100'000); i <= 100'000; ++i)
     453             :         {
     454             :             // decimal
     455             :             {
     456      200001 :                 std::stringstream ss;
     457      200001 :                 ss << (i >= 0 && (rand() & 1) ? "+" : "") << i;
     458      200001 :                 std::string str(ss.str());
     459      200001 :                 CATCH_REQUIRE(as2js::is_integer(str));
     460      200001 :                 CATCH_REQUIRE(as2js::is_floating_point(str));
     461      200001 :                 CATCH_REQUIRE(as2js::is_number(str));
     462      200001 :                 CATCH_REQUIRE(as2js::to_integer(str) == i);
     463             : #pragma GCC diagnostic push
     464             : #pragma GCC diagnostic ignored "-Wfloat-equal"
     465      200001 :                 bool const is_equal(as2js::to_floating_point(str) == static_cast<double>(i));
     466             : #pragma GCC diagnostic pop
     467      200001 :                 CATCH_REQUIRE(is_equal);
     468      200001 :                 CATCH_REQUIRE(as2js::is_true(str));
     469             : 
     470             :                 // no letter can follow an integer
     471             :                 //
     472      200001 :                 ss << (rand() % 26 + 'a');
     473      200001 :                 CATCH_REQUIRE(as2js::is_integer(ss.str()));
     474      200001 :             }
     475             : 
     476             :             // hexadecimal
     477             :             {
     478             :                 // not that in C/C++ hexadecimal numbers cannot really be
     479             :                 // negative; in JavaScript it's fine
     480             :                 //
     481      200001 :                 std::stringstream ss;
     482      200001 :                 ss << (i < 0 ? "-" : (rand() & 1 ? "+" : "")) << "0" << (rand() & 1 ? "x" : "X") << std::hex << labs(i);
     483      200001 :                 std::string const str(ss.str());
     484      200001 :                 CATCH_REQUIRE(as2js::is_integer(str));
     485      200001 :                 CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     486      200001 :                 CATCH_REQUIRE(as2js::is_number(str));
     487      200001 :                 CATCH_REQUIRE(as2js::to_integer(str) == i);
     488      200001 :                 CATCH_REQUIRE(std::isnan(as2js::to_floating_point(str)));
     489      200001 :                 CATCH_REQUIRE(as2js::is_true(str));
     490             : 
     491             :                 // add an 'h' at the end and it fails the integer test
     492             :                 //
     493      200001 :                 ss << 'h';
     494      200001 :                 CATCH_REQUIRE_FALSE(as2js::is_integer(ss.str()));
     495      200001 :             }
     496             : 
     497      200001 :             if(i >= 0)
     498             :             {
     499             :                 // some characters at the start mean this is not a number
     500             :                 //
     501      100001 :                 std::stringstream ss;
     502      100001 :                 ss << ',' << i;
     503      100001 :                 std::string str(ss.str());
     504      100001 :                 CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     505      100001 :                 CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     506      100001 :                 CATCH_REQUIRE_FALSE(as2js::is_number(str));
     507             : 
     508      100001 :                 str[0] = '/';
     509      100001 :                 CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     510      100001 :                 CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     511      100001 :                 CATCH_REQUIRE_FALSE(as2js::is_number(str));
     512             : 
     513      100001 :                 str[0] = '|';
     514      100001 :                 CATCH_REQUIRE_FALSE(as2js::is_integer(str));
     515      100001 :                 CATCH_REQUIRE_FALSE(as2js::is_floating_point(str));
     516      100001 :                 CATCH_REQUIRE_FALSE(as2js::is_number(str));
     517      100001 :             }
     518             :         }
     519             :     }
     520          15 :     CATCH_END_SECTION()
     521             : 
     522          15 :     CATCH_START_SECTION("string_number: floating points")
     523             :     {
     524        3351 :         for(double i(-1000.00); i <= 1000.00; i += (rand() % 120) / 100.0)
     525             :         {
     526        3350 :             std::stringstream ss;
     527        3350 :             ss << i;
     528        6700 :             if(ss.str().find('e') != std::string::npos
     529        6700 :             || ss.str().find('E') != std::string::npos)
     530             :             {
     531             :                 // this happens with numbers very close to zero and the
     532             :                 // system decides to write them as '1e-12' for example
     533             :                 //
     534             :                 // Note: does not matter if it does not happen
     535             :                 //
     536           0 :                 continue;
     537             :             }
     538        3350 :             std::string const str1(ss.str());
     539        3350 :             std::int64_t const integer1(lrint(i));
     540        3350 :             bool const is_integer1(std::find(str1.cbegin(), str1.cend(), '.') == str1.cend());
     541        3350 :             std::string str1_without0;
     542             : 
     543        3350 :             CATCH_REQUIRE(as2js::is_integer(str1) == is_integer1);
     544        3350 :             CATCH_REQUIRE(as2js::is_floating_point(str1));
     545        3350 :             if(str1.length() >= 3
     546        3349 :             && str1[0] == '0'
     547        6699 :             && str1[1] == '.')
     548             :             {
     549             :                 // test without the starting '0' and it works too
     550             :                 //
     551           1 :                 str1_without0 = str1.substr(1);
     552           1 :                 CATCH_REQUIRE(as2js::is_floating_point(str1_without0));
     553             :             }
     554        3350 :             CATCH_REQUIRE(as2js::is_number(str1));
     555        3350 :             CATCH_REQUIRE(as2js::is_true(str1));
     556        3350 :             if(is_integer1)
     557             :             {
     558          35 :                 CATCH_REQUIRE(as2js::to_integer(str1) == integer1);
     559             :             }
     560             :             else
     561             :             {
     562        3315 :                 CATCH_REQUIRE_THROWS_MATCHES(
     563             :                       as2js::to_integer(str1)
     564             :                     , as2js::internal_error
     565             :                     , Catch::Matchers::ExceptionMessage(
     566             :                               "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     567             :             }
     568        3350 :             CATCH_REQUIRE(close_double(as2js::to_floating_point(str1), i, 0.01));
     569        3350 :             if(!str1_without0.empty())
     570             :             {
     571           1 :                 CATCH_REQUIRE(close_double(as2js::to_floating_point(str1_without0), i, 0.01));
     572             :             }
     573             : 
     574             :             // add x 1000 as an exponent
     575        3350 :             ss << "e" << ((rand() & 1) != 0 ? "+" : "") << "3";
     576        3350 :             std::string const str2(ss.str());
     577             :             // the 'e' "breaks" the integer test in JavaScript
     578        3350 :             CATCH_REQUIRE_FALSE(as2js::is_integer(str2));
     579        3350 :             CATCH_REQUIRE(as2js::is_floating_point(str2));
     580        3350 :             CATCH_REQUIRE(as2js::is_number(str2));
     581        3350 :             CATCH_REQUIRE(as2js::is_true(str2));
     582        3350 :             CATCH_REQUIRE_THROWS_MATCHES(
     583             :                   as2js::to_integer(str2)
     584             :                 , as2js::internal_error
     585             :                 , Catch::Matchers::ExceptionMessage(
     586             :                           "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     587        3350 :             CATCH_REQUIRE(close_double(as2js::to_floating_point(str2), i * 1000.0, 0.01));
     588             : 
     589             :             // add / 1000 as an exponent
     590        3350 :             ss.str(""); // reset the string
     591        3350 :             ss << i << "e-3";
     592        3350 :             std::string const str3(ss.str());
     593             :             // the 'e' "breaks" the integer test in JavaScript
     594        3350 :             CATCH_REQUIRE_FALSE(as2js::is_integer(str3));
     595        3350 :             CATCH_REQUIRE(as2js::is_floating_point(str3));
     596        3350 :             CATCH_REQUIRE(as2js::is_number(str3));
     597        3350 :             CATCH_REQUIRE(as2js::is_true(str3));
     598        3350 :             CATCH_REQUIRE_THROWS_MATCHES(
     599             :                   as2js::to_integer(str3)
     600             :                 , as2js::internal_error
     601             :                 , Catch::Matchers::ExceptionMessage(
     602             :                           "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     603        3350 :             CATCH_REQUIRE(close_double(as2js::to_floating_point(str3), i / 1000.0, 0.00001));
     604        3350 :         }
     605             : 
     606             :         // the exponent must start with e and + or -, other characters are
     607             :         // not valid
     608             :         //
     609           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("3.5e,7"));
     610           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("-7.02E|9"));
     611           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("3.5e!7"));
     612           1 :         CATCH_REQUIRE(as2js::is_floating_point("3.5e09")); // this one is valid, the exponent can start with a '0'!
     613           1 :         CATCH_REQUIRE(as2js::is_floating_point("3.5e90")); // this one is an edge case, number starting with '9'
     614           1 :         CATCH_REQUIRE(as2js::is_floating_point("3.5e0123456789")); // another edge case
     615             : 
     616             :         // without at least one digit, it's not a valid floating point
     617             :         //
     618           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("-"));
     619           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("+"));
     620           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("-."));
     621           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("+."));
     622           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("-e"));
     623           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("+e"));
     624           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("-E"));
     625           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("+E"));
     626           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("-.e"));
     627           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("+.e"));
     628           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("-.E"));
     629           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("+.E"));
     630           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("e-3"));
     631           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("e+4"));
     632           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("E-5"));
     633           1 :         CATCH_REQUIRE_FALSE(as2js::is_floating_point("E+6"));
     634             :     }
     635          15 :     CATCH_END_SECTION()
     636             : 
     637          15 :     CATCH_START_SECTION("string_number: random 64 bits integers")
     638             :     {
     639             :         // a few more using random
     640      100001 :         for(int i(0); i < 100000; ++i)
     641             :         {
     642      100000 :             std::int64_t value(0);
     643      100000 :             SNAP_CATCH2_NAMESPACE::random(value);
     644      100000 :             std::stringstream ss;
     645      100000 :             ss << value;
     646      100000 :             std::string const str(ss.str());
     647      100000 :             CATCH_REQUIRE(as2js::is_integer(str));
     648      100000 :             CATCH_REQUIRE(as2js::is_floating_point(str));
     649      100000 :             CATCH_REQUIRE(as2js::is_number(str));
     650      100000 :             CATCH_REQUIRE(as2js::is_true(str));
     651      100000 :             CATCH_REQUIRE(as2js::to_integer(str) == value);
     652             : 
     653             :             // this is important since double mantissa is only 52 bits
     654             :             // and here our integral numbers are 64 bits
     655             :             //
     656      100000 :             as2js::floating_point const flt1(as2js::to_floating_point(str));
     657      100000 :             as2js::floating_point const flt2(static_cast<as2js::floating_point::value_type>(value));
     658      100000 :             CATCH_REQUIRE(flt1.nearly_equal(flt2, 0.0001));
     659      100000 :             CATCH_REQUIRE(flt2.nearly_equal(flt1, 0.0001));
     660      100000 :         }
     661             :     }
     662          15 :     CATCH_END_SECTION()
     663             : 
     664          15 :     CATCH_START_SECTION("string_number: NULL value")
     665             :     {
     666             :         // test a few non-hexadecimal numbers
     667             :         //
     668         101 :         for(int i(0); i < 100; ++i)
     669             :         {
     670             :             // get a character which is not a valid hex digit and not '\0'
     671             :             // and not 0x7F (Del)
     672             :             //
     673             :             char c;
     674             :             do
     675             :             {
     676         124 :                 c = static_cast<char>(rand() % 0x7D + 1);
     677             :             }
     678          69 :             while((c >= '0' && c <= '9')
     679         112 :                || (c >= 'a' && c <= 'f')
     680         230 :                || (c >= 'A' && c <= 'F'));
     681             : 
     682             :             // bad character is right at the beginning of the hex number
     683         100 :             std::stringstream ss1;
     684         100 :             ss1 << "0" << (rand() & 1 ? "x" : "X") << c << "123ABC";
     685         100 :             std::string str1(ss1.str());
     686         100 :             CATCH_REQUIRE_FALSE(as2js::is_integer(str1));
     687         100 :             CATCH_REQUIRE_FALSE(as2js::is_floating_point(str1));
     688         100 :             CATCH_REQUIRE_FALSE(as2js::is_number(str1));
     689         100 :             CATCH_REQUIRE(as2js::is_true(str1));
     690         100 :             CATCH_REQUIRE_THROWS_MATCHES(
     691             :                   as2js::to_integer(str1)
     692             :                 , as2js::internal_error
     693             :                 , Catch::Matchers::ExceptionMessage(
     694             :                           "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     695         100 :             CATCH_REQUIRE(std::isnan(as2js::to_floating_point(str1)));
     696             : 
     697             :             // invalid character is in the middle of the hex number
     698             :             //
     699         100 :             std::stringstream ss2;
     700         100 :             ss2 << "0" << (rand() & 1 ? "x" : "X") << "123" << c << "ABC";
     701         100 :             std::string str2(ss2.str());
     702         100 :             CATCH_REQUIRE_FALSE(as2js::is_integer(str2));
     703         100 :             CATCH_REQUIRE_FALSE(as2js::is_floating_point(str2));
     704         100 :             CATCH_REQUIRE_FALSE(as2js::is_number(str2));
     705         100 :             CATCH_REQUIRE(as2js::is_true(str2));
     706         100 :             CATCH_REQUIRE_THROWS_MATCHES(
     707             :                   as2js::to_integer(str2)
     708             :                 , as2js::internal_error
     709             :                 , Catch::Matchers::ExceptionMessage(
     710             :                           "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     711         100 :             CATCH_REQUIRE(std::isnan(as2js::to_floating_point(str2)));
     712             : 
     713             :             // invalid character is at the very end of the hex number
     714             :             //
     715         100 :             std::stringstream ss3;
     716         100 :             ss3 << "0" << (rand() & 1 ? "x" : "X") << "123ABC" << c;
     717         100 :             std::string str3(ss3.str());
     718         100 :             CATCH_REQUIRE_FALSE(as2js::is_integer(str3));
     719         100 :             CATCH_REQUIRE_FALSE(as2js::is_floating_point(str3));
     720         100 :             CATCH_REQUIRE_FALSE(as2js::is_number(str3));
     721         100 :             CATCH_REQUIRE(as2js::is_true(str3));
     722         100 :             CATCH_REQUIRE_THROWS_MATCHES(
     723             :                   as2js::to_integer(str3)
     724             :                 , as2js::internal_error
     725             :                 , Catch::Matchers::ExceptionMessage(
     726             :                           "internal_error: to_integer(std::string const & s) called with an invalid integer."));
     727         100 :             CATCH_REQUIRE(std::isnan(as2js::to_floating_point(str3)));
     728         100 :         }
     729             :     }
     730          15 :     CATCH_END_SECTION()
     731          15 : }
     732             : 
     733             : 
     734          18 : CATCH_TEST_CASE("string_simplify", "[string][type]")
     735             : {
     736          18 :     CATCH_START_SECTION("string_simplify: only spaces")
     737             :     {
     738           2 :         std::string const str("        ");
     739           1 :         std::string const simplified(as2js::simplify(str));
     740           1 :         CATCH_REQUIRE(simplified == "0");
     741           1 :     }
     742          18 :     CATCH_END_SECTION()
     743             : 
     744          18 :     CATCH_START_SECTION("string_simplify: starting spaces")
     745             :     {
     746           2 :         std::string const str("    blah");
     747           1 :         std::string const simplified(as2js::simplify(str));
     748           1 :         CATCH_REQUIRE(simplified == "blah");
     749           1 :     }
     750          18 :     CATCH_END_SECTION()
     751             : 
     752          18 :     CATCH_START_SECTION("string_simplify: ending spaces")
     753             :     {
     754           2 :         std::string const str("blah    ");
     755           1 :         std::string const simplified(as2js::simplify(str));
     756           1 :         CATCH_REQUIRE(simplified == "blah");
     757           1 :     }
     758          18 :     CATCH_END_SECTION()
     759             : 
     760          18 :     CATCH_START_SECTION("string_simplify: starting & ending spaces")
     761             :     {
     762           2 :         std::string const str("    blah    ");
     763           1 :         std::string const simplified(as2js::simplify(str));
     764           1 :         CATCH_REQUIRE(simplified == "blah");
     765           1 :     }
     766          18 :     CATCH_END_SECTION()
     767             : 
     768          18 :     CATCH_START_SECTION("string_simplify: inside spaces")
     769             :     {
     770           2 :         std::string const str("blah    foo");
     771           1 :         std::string const simplified(as2js::simplify(str));
     772           1 :         CATCH_REQUIRE(simplified == "blah foo");
     773           1 :     }
     774          18 :     CATCH_END_SECTION()
     775             : 
     776          18 :     CATCH_START_SECTION("string_simplify: simplify starting, inside, and ending spaces")
     777             :     {
     778           2 :         std::string const str("    blah    foo    ");
     779           1 :         std::string const simplified(as2js::simplify(str));
     780           1 :         CATCH_REQUIRE(simplified == "blah foo");
     781           1 :     }
     782          18 :     CATCH_END_SECTION()
     783             : 
     784          18 :     CATCH_START_SECTION("string_simplify: simplify spaces including newlines")
     785             :     {
     786           2 :         std::string const str("blah  \n  foo");
     787           1 :         std::string const simplified(as2js::simplify(str));
     788           1 :         CATCH_REQUIRE(simplified == "blah foo");
     789           1 :     }
     790          18 :     CATCH_END_SECTION()
     791             : 
     792          18 :     CATCH_START_SECTION("string_simplify: empty string becomes zero")
     793             :     {
     794           1 :         std::string const str;
     795           1 :         std::string const simplified(as2js::simplify(str));
     796           1 :         CATCH_REQUIRE(simplified == "0");
     797           1 :     }
     798          18 :     CATCH_END_SECTION()
     799             : 
     800          18 :     CATCH_START_SECTION("string_simplify: spaces only string becomes zero")
     801             :     {
     802           2 :         std::string const str("     ");
     803           1 :         std::string const simplified(as2js::simplify(str));
     804           1 :         CATCH_REQUIRE(simplified == "0");
     805           1 :     }
     806          18 :     CATCH_END_SECTION()
     807             : 
     808          18 :     CATCH_START_SECTION("string_simplify: simplify number with spaces around")
     809             :     {
     810           2 :         std::string const str("  3.14159  ");
     811           1 :         std::string const simplified(as2js::simplify(str));
     812           1 :         CATCH_REQUIRE(simplified == "3.14159");
     813           1 :         CATCH_REQUIRE_FALSE(as2js::is_integer(simplified));
     814           1 :         CATCH_REQUIRE(as2js::is_floating_point(simplified));
     815           1 :         CATCH_REQUIRE(as2js::is_number(simplified));
     816           1 :         CATCH_REQUIRE(as2js::floating_point(as2js::to_floating_point(simplified)).nearly_equal(3.14159, 1.0e-8));
     817           1 :     }
     818          18 :     CATCH_END_SECTION()
     819             : 
     820          18 :     CATCH_START_SECTION("string_simplify: simplify number with left over")
     821             :     {
     822           2 :         std::string const str("  3.14159 ignore that part  ");
     823           1 :         std::string const simplified(as2js::simplify(str));
     824           1 :         CATCH_REQUIRE(simplified == "3.14159");
     825           1 :         CATCH_REQUIRE_FALSE(as2js::is_integer(simplified));
     826           1 :         CATCH_REQUIRE(as2js::is_floating_point(simplified));
     827           1 :         CATCH_REQUIRE(as2js::is_number(simplified));
     828           1 :         CATCH_REQUIRE(as2js::floating_point(as2js::to_floating_point(simplified)).nearly_equal(3.14159, 1.0e-8));
     829           1 :     }
     830          18 :     CATCH_END_SECTION()
     831             : 
     832          18 :     CATCH_START_SECTION("string_simplify: simplify positive number with left over")
     833             :     {
     834           2 :         std::string const str("  +3.14159 ignore that part  ");
     835           1 :         std::string const simplified(as2js::simplify(str));
     836           1 :         CATCH_REQUIRE(simplified == "+3.14159");
     837           1 :         CATCH_REQUIRE(as2js::is_floating_point(simplified));
     838           1 :         CATCH_REQUIRE(as2js::is_number(simplified));
     839           1 :         CATCH_REQUIRE(as2js::floating_point(as2js::to_floating_point(simplified)).nearly_equal(3.14159, 1.0e-8));
     840           1 :     }
     841          18 :     CATCH_END_SECTION()
     842             : 
     843          18 :     CATCH_START_SECTION("string_simplify: simplify negative integer with left over")
     844             :     {
     845           2 :         std::string const str("  -314159 ignore that part  ");
     846           1 :         std::string const simplified(as2js::simplify(str));
     847           1 :         CATCH_REQUIRE(simplified == "-314159");
     848           1 :         CATCH_REQUIRE(as2js::is_integer(simplified));
     849           1 :         CATCH_REQUIRE(as2js::to_integer(simplified) == -314159);
     850           1 :         CATCH_REQUIRE(as2js::is_floating_point(simplified));
     851           1 :         CATCH_REQUIRE(as2js::is_number(simplified));
     852           1 :         CATCH_REQUIRE(as2js::floating_point(as2js::to_floating_point(simplified)).nearly_equal(-314159.0, 1.0e-8));
     853           1 :     }
     854          18 :     CATCH_END_SECTION()
     855             : 
     856          18 :     CATCH_START_SECTION("string_simplify: simplify the positive number with exponent and left over")
     857             :     {
     858           2 :         std::string const str("  +0.00314159e3 ignore that part  ");
     859           1 :         std::string const simplified(as2js::simplify(str));
     860           1 :         CATCH_REQUIRE(simplified == "+0.00314159e3");
     861           1 :         CATCH_REQUIRE(as2js::is_floating_point(simplified));
     862           1 :         CATCH_REQUIRE(as2js::is_number(simplified));
     863           1 :         CATCH_REQUIRE(as2js::floating_point(as2js::to_floating_point(simplified)).nearly_equal(3.14159, 1e-8));
     864           1 :     }
     865          18 :     CATCH_END_SECTION()
     866             : 
     867          18 :     CATCH_START_SECTION("string_simplify: simplify the positive number with positive exponent and left over")
     868             :     {
     869           2 :         std::string const str("  +0.00314159e+3 ignore that part  ");
     870           1 :         std::string const simplified(as2js::simplify(str));
     871           1 :         CATCH_REQUIRE(simplified == "+0.00314159e+3");
     872           1 :         CATCH_REQUIRE(as2js::is_floating_point(simplified));
     873           1 :         CATCH_REQUIRE(as2js::is_number(simplified));
     874           1 :         CATCH_REQUIRE(as2js::floating_point(as2js::to_floating_point(simplified)).nearly_equal(3.14159, 1e-8));
     875           1 :     }
     876          18 :     CATCH_END_SECTION()
     877             : 
     878          18 :     CATCH_START_SECTION("string_simplify: simplify the negative number with negative exponent and left over")
     879             :     {
     880           2 :         std::string const str("  -314159e-5 ignore that part  ");
     881           1 :         std::string const simplified(as2js::simplify(str));
     882           1 :         CATCH_REQUIRE(simplified == "-314159");
     883           1 :         CATCH_REQUIRE(as2js::is_integer(simplified));
     884           1 :         CATCH_REQUIRE(as2js::to_integer(simplified) == -314159);
     885           1 :         CATCH_REQUIRE(as2js::is_floating_point(simplified));
     886           1 :         CATCH_REQUIRE(as2js::is_number(simplified));
     887           1 :         CATCH_REQUIRE(as2js::floating_point(as2js::to_floating_point(simplified)).nearly_equal(-314159, 1e-8));
     888           1 :     }
     889          18 :     CATCH_END_SECTION()
     890             : 
     891          18 :     CATCH_START_SECTION("string_simplify: simplify negative number with negative exponent and left over")
     892             :     {
     893           2 :         std::string str("  -314159.e-5 ignore that part  ");
     894           1 :         std::string simplified(as2js::simplify(str));
     895           1 :         CATCH_REQUIRE(simplified == "-314159.e-5");
     896           1 :         CATCH_REQUIRE(as2js::is_floating_point(simplified));
     897           1 :         CATCH_REQUIRE(as2js::is_number(simplified));
     898           1 :         CATCH_REQUIRE(as2js::floating_point(as2js::to_floating_point(simplified)).nearly_equal(-3.14159, 1e-8));
     899           1 :     }
     900          18 :     CATCH_END_SECTION()
     901             : 
     902          18 :     CATCH_START_SECTION("string_simplify: simplify negative number with large negative exponent and left over")
     903             :     {
     904           2 :         std::string str("  -314159.0e-105ignorethatpart");
     905           1 :         std::string simplified(as2js::simplify(str));
     906           1 :         CATCH_REQUIRE(simplified == "-314159.0e-105");
     907           1 :         CATCH_REQUIRE(as2js::is_floating_point(simplified));
     908           1 :         CATCH_REQUIRE(as2js::is_number(simplified));
     909           1 :         CATCH_REQUIRE(as2js::floating_point(as2js::to_floating_point(simplified)).nearly_equal(-3.14159e-100, 1e-8));
     910           1 :     }
     911          18 :     CATCH_END_SECTION()
     912          18 : }
     913             : 
     914             : 
     915             : 
     916             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.14