FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Fix flgBaseWriter to use kParseNumbersAsStringsFlag instead of kParseFullPrecisionFlag by AntonDevil · Pull Request #241 · NPP-JSONViewer/JSON-Viewer · GitHub

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .cpp  (3) .h  (1) All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
8 changes: 7 additions & 1 deletion src/NppJsonViewer/JsonHandler.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,14 @@ struct Result
using LE = rj::LineEndingOption;
using LF = rj::PrettyFormatOptions;

// Parse flags for all JSON operations. Historically flgBaseWriter used kParseFullPrecisionFlag
// instead of kParseNumbersAsStringsFlag because upstream RapidJSON's RawNumber() would quote
// numbers as strings. Our fork fixes that (RawNumber now writes via WriteRawValue without quotes),
// so both flag sets are now identical. They are kept separate to allow independent tuning of the
// DOM-based path (flgBaseReader: sort-by-key) vs the SAX streaming path (flgBaseWriter: format/compress)
// if needed in the future.
constexpr auto flgBaseReader = rj::kParseEscapedApostropheFlag | rj::kParseNanAndInfFlag | rj::kParseNumbersAsStringsFlag;
constexpr auto flgBaseWriter = rj::kParseEscapedApostropheFlag | rj::kParseNanAndInfFlag | rj::kParseFullPrecisionFlag;
constexpr auto flgBaseWriter = rj::kParseEscapedApostropheFlag | rj::kParseNanAndInfFlag | rj::kParseNumbersAsStringsFlag;

class JsonHandler
{
Expand Down
24 changes: 12 additions & 12 deletions tests/UnitTest/JsonCompressTest.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ namespace JsonCompress
std::unordered_map<std::string, std::string> testData {
{"{\r\n \"NaN\": NaN\r\n}", R"({"NaN":NaN})"},
{"{\r\n \"Mixed\": [\r\n null,\r\n null,\r\n \"power\"\r\n ]\r\n}", R"({"Mixed":[null,null,"power"]})"},
{"{\n \"Inf\": [\n -Infinity,\n Infinity,\n -Inf,\n Inf\n ]\n}", R"({"Inf":[-Infinity,Infinity,-Infinity,Infinity]})"},
{"{\n \"Inf\": [\n -Infinity,\n Infinity,\n -Inf,\n Inf\n ]\n}", R"({"Inf":[-Infinity,Infinity,-Inf,Inf]})"},
};

for (const auto& [input, output] : testData)
Expand Down Expand Up @@ -176,17 +176,17 @@ namespace JsonCompress
TEST_F(JsonCompressTest, CompressJson_numbers)
{
std::unordered_map<std::string, std::string> testData {
{R"({"num": 12.148681171238422})", "12.148681171238422"}, // All good
{R"({"num": 42.835353759876654})", "42.835353759876654"}, // All good
{R"({"num": 5.107091491635510056019771245})", "5.10709149163551"}, // Fine: Rounded up
{R"({"num": 100000000302052988.0})", "100000000302052990.0"}, // Fine: Rounded up
{R"({"num": 12.148681171238427111})", "12.148681171238428"}, // Fine: Rounded down
{R"({"num": 42.8353537598766541666})", "42.835353759876654"}, // Fine: Rounded up
{R"({"num": -1722.1864265316147})", "-1722.1864265316146"}, // This is interesting. Why last digit changed.
{R"({"num": -1722.1864265316148})", "-1722.1864265316149"}, // This is interesting. Why last digit changed.
{R"({"num": -172345.18642653167979})", "-172345.18642653167"}, // This is interesting. Why not rounded up.
{R"({"num": 1.234e5})", "123400.0"}, // Don't know how to fix.
{R"({"num": 0.0000001000})", "1e-7"}, // Don't know how to fix.
{R"({"num": 12.148681171238422})", "12.148681171238422"},
{R"({"num": 42.835353759876654})", "42.835353759876654"},
{R"({"num": 5.107091491635510056019771245})", "5.107091491635510056019771245"},
{R"({"num": 100000000302052988.0})", "100000000302052988.0"},
{R"({"num": 12.148681171238427111})", "12.148681171238427111"},
{R"({"num": 42.8353537598766541666})", "42.8353537598766541666"},
{R"({"num": -1722.1864265316147})", "-1722.1864265316147"},
{R"({"num": -1722.1864265316148})", "-1722.1864265316148"},
{R"({"num": -172345.18642653167979})", "-172345.18642653167979"},
{R"({"num": 1.234e5})", "1.234e5"},
{R"({"num": 0.0000001000})", "0.0000001000"},
};

for (const auto& [input, output] : testData)
Expand Down
89 changes: 45 additions & 44 deletions tests/UnitTest/JsonFormatTest.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ namespace JsonFormat
{R"({"NaN":NaN})", "{\r\n \"NaN\": NaN\r\n}"},
{R"({"Mixed":[null,null,"power"]})", "{\r\n \"Mixed\": [\r\n null,\r\n null,\r\n \"power\"\r\n ]\r\n}"},
{R"({"Inf":[-Infinity, Infinity, -Inf, Inf]})",
"{\r\n \"Inf\": [\r\n -Infinity,\r\n Infinity,\r\n -Infinity,\r\n Infinity\r\n ]\r\n}"},
"{\r\n \"Inf\": [\r\n -Infinity,\r\n Infinity,\r\n -Inf,\r\n Inf\r\n ]\r\n}"},
};

LE lineEndingOption = rj::kCrLf; // Windows line ending
Expand All @@ -196,7 +196,7 @@ namespace JsonFormat
std::unordered_map<std::string, std::string> testData {
{R"({"NaN":NaN})", "{\r\n \"NaN\": NaN\r\n}"},
{R"({"Mixed":[null,null,"power"]})", "{\r\n \"Mixed\": [null, null, \"power\"]\r\n}"},
{R"({"Inf":[-Infinity, Infinity, -Inf, Inf]})", "{\r\n \"Inf\": [-Infinity, Infinity, -Infinity, Infinity]\r\n}"},
{R"({"Inf":[-Infinity, Infinity, -Inf, Inf]})", "{\r\n \"Inf\": [-Infinity, Infinity, -Inf, Inf]\r\n}"},
};

LE lineEndingOption = rj::kCrLf; // Windows line ending
Expand Down Expand Up @@ -242,50 +242,51 @@ namespace JsonFormat
char indentChar = ' '; // space indented
unsigned indentLen = 4; // No indentation

// With kParseNumbersAsStringsFlag, numbers are preserved as exact original text
const std::unordered_map<std::string, std::string> testData {
{R"({"num": 12.148681171238422})", "12.148681171238422"}, // All good
{R"({"num": 42.835353759876654})", "42.835353759876654"}, // All good
{R"({"num": 5.107091491635510056019771245})", "5.10709149163551"}, // Fine: Rounded up
{R"({"num": 100000000302052988.0})", "100000000302052990.0"}, // Fine: Rounded up
{R"({"num": 42.8353537598766541666})", "42.835353759876654"}, // Fine: Rounded up
{R"({"num": 0.184467440737095516159})", "0.1844674407370955"}, // Fine: Rounded down
{R"({"num": 12.148681171238427111})", "12.148681171238428"}, // Rounded up. But why?
{R"({"num": -1722.1864265316147})", "-1722.1864265316146"}, // This is interesting. Why last digit changed.
{R"({"num": -1722.1864265316148})", "-1722.1864265316149"}, // This is interesting. Why last digit changed.
{R"({"num": -172345.18642653167979})", "-172345.18642653167"}, // This is interesting. Why not rounded up.
{R"({"num": 1.234e5})", "123400.0"}, // -------------------------------------
{R"({"num": 0.0000001000})", "1e-7"}, // Don't know how to fix all the below.
{R"({"num":-5.0975200963490517E-33})", "-5.097520096349052e-33"}, // -------------------------------------
{R"({"num":-6.3809366960906694E-48})", "-6.38093669609067e-48"},
{R"({"num":-7.4034655373995265E-78})", "-7.403465537399527e-78"},
{R"({"num":-7.7377839245507245E-78})", "-7.737783924550725e-78"},
{R"({"num":1.2859736125485259E-22, })", "1.285973612548526e-22"},
{R"({"num":-3.5403485244736897E-88})", "-3.54034852447369e-88"},
{R"({"num": 12.148681171238422})", "12.148681171238422"},
{R"({"num": 42.835353759876654})", "42.835353759876654"},
{R"({"num": 5.107091491635510056019771245})", "5.107091491635510056019771245"},
{R"({"num": 100000000302052988.0})", "100000000302052988.0"},
{R"({"num": 42.8353537598766541666})", "42.8353537598766541666"},
{R"({"num": 0.184467440737095516159})", "0.184467440737095516159"},
{R"({"num": 12.148681171238427111})", "12.148681171238427111"},
{R"({"num": -1722.1864265316147})", "-1722.1864265316147"},
{R"({"num": -1722.1864265316148})", "-1722.1864265316148"},
{R"({"num": -172345.18642653167979})", "-172345.18642653167979"},
{R"({"num": 1.234e5})", "1.234e5"},
{R"({"num": 0.0000001000})", "0.0000001000"},
{R"({"num":-5.0975200963490517E-33})", "-5.0975200963490517E-33"},
{R"({"num":-6.3809366960906694E-48})", "-6.3809366960906694E-48"},
{R"({"num":-7.4034655373995265E-78})", "-7.4034655373995265E-78"},
{R"({"num":-7.7377839245507245E-78})", "-7.7377839245507245E-78"},
{R"({"num":1.2859736125485259E-22, })", "1.2859736125485259E-22"},
{R"({"num":-3.5403485244736897E-88})", "-3.5403485244736897E-88"},
{R"({"num":-6553693.3617752995})", "-6553693.3617752995"},
{R"({"num":-6.8141086401061905E-44})", "-6.814108640106191e-44"},
{R"({"num":5.5843284390697506E-71})", "5.584328439069751e-71"},
{R"({"num":-4.3180528943019356E-77})", "-4.318052894301936e-77"},
{R"({"num":-5.8231387142089446E-34})", "-5.823138714208945e-34"},
{R"({"num":4.9686769279508796E-34})", "4.96867692795088e-34"},
{R"({"num":-1.7271559814272259E-77})", "-1.727155981427226e-77"},
{R"({"num":-4.2596088775464085E-81})", "-4.259608877546409e-81"},
{R"({"num":3.7049941506206046E-71})", "3.704994150620605e-71"},
{R"({"num":3.9742364030067576E-86})", "3.974236403006758e-86"},
{R"({"num":3.1628542535929037E-89})", "3.162854253592904e-89"},
{R"({"num":-268.52143589416397})", "-268.521435894164"},
{R"({"num":-2.2795405986944148E-93})", "-2.279540598694415e-93"},
{R"({"num":-7.3921473885461993E-95})", "-7.3921473885462e-95"},
{R"({"num":-5.1970028999668327E-45})", "-5.197002899966833e-45"},
{R"({"num":3.5937267475433058E-09})", "3.593726747543306e-9"},
{R"({"num":7.2781313854297585E-75})", "7.278131385429759e-75"},
{R"({"num":2.1823857766614118E-78})", "2.182385776661412e-78"},
{R"({"num":8.9080568887277594E-11})", "8.90805688872776e-11"},
{R"({"num":-898453.63759556494})", "-898453.637595565"},
{R"({"num":-6.5029793100887976E-55})", "-6.502979310088798e-55"},
{R"({"num":15650583.101212589})", "15650583.10121259"},
{R"({"num":-7.7306921203660293E-55})", "-7.73069212036603e-55"},
{R"({"num":4.3436060211811726E-74})", "4.343606021181173e-74"},
{R"({"num":-7.1399486851522386E-90})", "-7.139948685152239e-9"},
{R"({"num":-6.8141086401061905E-44})", "-6.8141086401061905E-44"},
{R"({"num":5.5843284390697506E-71})", "5.5843284390697506E-71"},
{R"({"num":-4.3180528943019356E-77})", "-4.3180528943019356E-77"},
{R"({"num":-5.8231387142089446E-34})", "-5.8231387142089446E-34"},
{R"({"num":4.9686769279508796E-34})", "4.9686769279508796E-34"},
{R"({"num":-1.7271559814272259E-77})", "-1.7271559814272259E-77"},
{R"({"num":-4.2596088775464085E-81})", "-4.2596088775464085E-81"},
{R"({"num":3.7049941506206046E-71})", "3.7049941506206046E-71"},
{R"({"num":3.9742364030067576E-86})", "3.9742364030067576E-86"},
{R"({"num":3.1628542535929037E-89})", "3.1628542535929037E-89"},
{R"({"num":-268.52143589416397})", "-268.52143589416397"},
{R"({"num":-2.2795405986944148E-93})", "-2.2795405986944148E-93"},
{R"({"num":-7.3921473885461993E-95})", "-7.3921473885461993E-95"},
{R"({"num":-5.1970028999668327E-45})", "-5.1970028999668327E-45"},
{R"({"num":3.5937267475433058E-09})", "3.5937267475433058E-09"},
{R"({"num":7.2781313854297585E-75})", "7.2781313854297585E-75"},
{R"({"num":2.1823857766614118E-78})", "2.1823857766614118E-78"},
{R"({"num":8.9080568887277594E-11})", "8.9080568887277594E-11"},
{R"({"num":-898453.63759556494})", "-898453.63759556494"},
{R"({"num":-6.5029793100887976E-55})", "-6.5029793100887976E-55"},
{R"({"num":15650583.101212589})", "15650583.101212589"},
{R"({"num":-7.7306921203660293E-55})", "-7.7306921203660293E-55"},
{R"({"num":4.3436060211811726E-74})", "4.3436060211811726E-74"},
{R"({"num":-7.1399486851522386E-90})", "-7.1399486851522386E-90"},
};

for (const auto& [input, output] : testData)
Expand Down
56 changes: 50 additions & 6 deletions tests/UnitTest/JsonSortByKeyTest.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,58 @@ namespace JsonSortByKey

TEST_F(JsonSortByKeyTest, TestSortJsonByKey_NumberPrecision_Success)
{
// Verify numbers survive the sort-by-key roundtrip without gaining quotes.
// Note: SortJsonByKey re-parses via FormatJson (which uses kParseFullPrecisionFlag),
// so very high precision may be normalized (e.g. 0.00000000000001 -> 1e-14).
// But they must NOT become strings (e.g. "3.14" or "12345678901234567890").
std::string inputJson = R"({"z": "last", "pi": 3.141592653589793, "tiny": 1e-14, "tiny2": 0.00000000000001, "big": 12345678901234567890})";
// Verify numbers survive the sort-by-key roundtrip without gaining quotes
// and with full precision preserved (synced with RapidJSON's Document.RawNumberRoundtrip_Precision test).
std::string inputJson = R"({"z": "last", "pi": 3.141592653589793238, "tiny": 1e-14, "tiny2": 0.00000000000001, "big": 12345678901234567890})";
auto result = m_jsonHandler.SortJsonByKey(inputJson, {}, {}, ' ', 2);

ASSERT_TRUE(result.success);
ASSERT_EQ(result.response, "{\n \"big\": 12345678901234567890,\n \"pi\": 3.141592653589793,\n \"tiny\": 1e-14,\n \"tiny2\": 1e-14,\n \"z\": \"last\"\n}");
ASSERT_EQ(result.response, "{\n \"big\": 12345678901234567890,\n \"pi\": 3.141592653589793238,\n \"tiny\": 1e-14,\n \"tiny2\": 0.00000000000001,\n \"z\": \"last\"\n}");
}

TEST_F(JsonSortByKeyTest, TestSortJsonByKey_NumberFormats_Success)
{
// Verify all valid JSON number notations survive sort-by-key roundtrip exactly
// (synced with RapidJSON's Document.RawNumberRoundtrip_NumberFormats test).
std::string inputJson =
R"({"neg_frac": -0.5,)"
R"( "int": 42,)"
R"( "neg": -17,)"
R"( "zero": 0,)"
R"( "frac": 3.14,)"
R"( "exp_lower": 1e10,)"
R"( "exp_upper": 1E10,)"
R"( "exp_plus": 1e+10,)"
R"( "exp_neg": 1e-10,)"
R"( "exp_frac": 1.5e3,)"
R"( "huge_int": 99999999999999999999,)"
R"( "huge_neg": -99999999999999999999,)"
R"( "tiny_exp": 1e-308,)"
R"( "tiny_frac": 0.000000000000000001,)"
R"( "leading_zero_frac": 0.123})";
auto result = m_jsonHandler.SortJsonByKey(inputJson, {}, {}, ' ', 2);

ASSERT_TRUE(result.success);

// Verify exact output with alphabetically sorted keys and preserved number text
std::string expected =
"{\n"
" \"exp_frac\": 1.5e3,\n"
" \"exp_lower\": 1e10,\n"
" \"exp_neg\": 1e-10,\n"
" \"exp_plus\": 1e+10,\n"
" \"exp_upper\": 1E10,\n"
" \"frac\": 3.14,\n"
" \"huge_int\": 99999999999999999999,\n"
" \"huge_neg\": -99999999999999999999,\n"
" \"int\": 42,\n"
" \"leading_zero_frac\": 0.123,\n"
" \"neg\": -17,\n"
" \"neg_frac\": -0.5,\n"
" \"tiny_exp\": 1e-308,\n"
" \"tiny_frac\": 0.000000000000000001,\n"
" \"zero\": 0\n"
"}";
ASSERT_EQ(result.response, expected);
}
} // namespace JsonSortByKey
Loading

Back | FazBrowse Home | New Git URL