Add json fmt test

This commit is contained in:
Maya Warrier 2023-09-13 21:07:40 -04:00
parent 3f250c5a98
commit 4de8d715e6
3 changed files with 52 additions and 9 deletions

View File

@ -312,9 +312,11 @@ parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, par
UC const * const end_of_integer_part = p;
int64_t digit_count = int64_t(end_of_integer_part - start_digits);
answer.integer = span<const UC>(start_digits, size_t(digit_count));
// disallow leading zeros
if (fmt == chars_format::json && start_digits[0] == UC('0') && digit_count > 1) {
return answer;
if (fmt == chars_format::json) {
// at least 1 digit in integer part, without leading zeros
if (digit_count == 0 || (start_digits[0] == UC('0') && digit_count > 1)) {
return answer;
}
}
int64_t exponent = 0;
@ -335,12 +337,13 @@ parsed_number_string_t<UC> parse_number_string(UC const *p, UC const * pend, par
answer.fraction = span<const UC>(before, size_t(p - before));
digit_count -= exponent;
}
// we must have encountered at least one integer!
if (digit_count == 0) {
return answer;
}
// or at least two if a decimal point exists, with json rules
else if (fmt == chars_format::json && has_decimal_point && digit_count == 1) {
if (fmt == chars_format::json) {
// at least 1 digit in fractional part
if (has_decimal_point && exponent == 0) {
return answer;
}
}
else if (digit_count == 0) { // we must have encountered at least one integer!
return answer;
}
int64_t exp_number = 0; // explicit exponential part

View File

@ -72,6 +72,8 @@ fast_float_add_cpp_test(long_test)
fast_float_add_cpp_test(powersoffive_hardround)
fast_float_add_cpp_test(string_test)
fast_float_add_cpp_test(json_fmt)
option(FASTFLOAT_EXHAUSTIVE "Exhaustive tests" OFF)

38
tests/json_fmt.cpp Normal file
View File

@ -0,0 +1,38 @@
#include <cstdlib>
#include <iostream>
#include <vector>
#include "fast_float/fast_float.h"
int main()
{
const std::vector<double> expected{ -0.2, 0.02, 0.002, 1., 0. };
const std::vector<std::string> accept{ "-0.2", "0.02", "0.002", "1e+0000", "0e-2" };
const std::vector<std::string> reject{ "-.2", "00.02", "0.e+1", "00.e+1", ".25"};
const auto fmt = fast_float::chars_format::json;
for (std::size_t i = 0; i < accept.size(); ++i)
{
const auto& f = accept[i];
double result;
auto answer = fast_float::from_chars(f.data(), f.data() + f.size(), result, fmt);
if (answer.ec != std::errc() || result != expected[i]) {
std::cerr << "json fmt rejected valid json " << f << std::endl;
return EXIT_FAILURE;
}
}
for (std::size_t i = 0; i < reject.size(); ++i)
{
const auto& f = reject[i];
double result;
auto answer = fast_float::from_chars(f.data(), f.data() + f.size(), result, fmt);
if (answer.ec == std::errc()) {
std::cerr << "json fmt accepted invalid json " << f << std::endl;
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}