|
14 | 14 | #include "jsontest.h"
|
15 | 15 | #include <cmath>
|
16 | 16 | #include <cstring>
|
| 17 | +#include <functional> |
17 | 18 | #include <iomanip>
|
18 | 19 | #include <iostream>
|
19 | 20 | #include <iterator>
|
@@ -63,27 +64,22 @@ static std::deque<JsonTest::TestCaseFactory> local_;
|
63 | 64 |
|
64 | 65 | struct ValueTest : JsonTest::TestCase {
|
65 | 66 | Json::Value null_;
|
66 |
| - Json::Value emptyArray_; |
67 |
| - Json::Value emptyObject_; |
68 |
| - Json::Value integer_; |
69 |
| - Json::Value unsignedInteger_; |
70 |
| - Json::Value smallUnsignedInteger_; |
71 |
| - Json::Value real_; |
72 |
| - Json::Value float_; |
| 67 | + Json::Value emptyArray_{Json::arrayValue}; |
| 68 | + Json::Value emptyObject_{Json::objectValue}; |
| 69 | + Json::Value integer_{123456789}; |
| 70 | + Json::Value unsignedInteger_{34567890}; |
| 71 | + Json::Value smallUnsignedInteger_{Json::Value::UInt(Json::Value::maxInt)}; |
| 72 | + Json::Value real_{1234.56789}; |
| 73 | + Json::Value float_{0.00390625f}; |
73 | 74 | Json::Value array1_;
|
74 | 75 | Json::Value object1_;
|
75 |
| - Json::Value emptyString_; |
76 |
| - Json::Value string1_; |
77 |
| - Json::Value string_; |
78 |
| - Json::Value true_; |
79 |
| - Json::Value false_; |
80 |
| - |
81 |
| - ValueTest() |
82 |
| - : emptyArray_(Json::arrayValue), emptyObject_(Json::objectValue), |
83 |
| - integer_(123456789), unsignedInteger_(34567890u), |
84 |
| - smallUnsignedInteger_(Json::Value::UInt(Json::Value::maxInt)), |
85 |
| - real_(1234.56789), float_(0.00390625f), emptyString_(""), string1_("a"), |
86 |
| - string_("sometext with space"), true_(true), false_(false) { |
| 76 | + Json::Value emptyString_{""}; |
| 77 | + Json::Value string1_{"a"}; |
| 78 | + Json::Value string_{"sometext with space"}; |
| 79 | + Json::Value true_{true}; |
| 80 | + Json::Value false_{false}; |
| 81 | + |
| 82 | + ValueTest() { |
87 | 83 | array1_.append(1234);
|
88 | 84 | object1_["id"] = 1234;
|
89 | 85 | }
|
@@ -124,53 +120,45 @@ struct ValueTest : JsonTest::TestCase {
|
124 | 120 | };
|
125 | 121 |
|
126 | 122 | Json::String ValueTest::normalizeFloatingPointStr(const Json::String& s) {
|
127 |
| - Json::String::size_type index = s.find_last_of("eE"); |
128 |
| - if (index != Json::String::npos) { |
129 |
| - Json::String::size_type hasSign = |
130 |
| - (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; |
131 |
| - Json::String::size_type exponentStartIndex = index + 1 + hasSign; |
132 |
| - Json::String normalized = s.substr(0, exponentStartIndex); |
133 |
| - Json::String::size_type indexDigit = |
134 |
| - s.find_first_not_of('0', exponentStartIndex); |
135 |
| - Json::String exponent = "0"; |
136 |
| - if (indexDigit != Json::String::npos) // There is an exponent different |
137 |
| - // from 0 |
138 |
| - { |
139 |
| - exponent = s.substr(indexDigit); |
140 |
| - } |
141 |
| - return normalized + exponent; |
| 123 | + auto index = s.find_last_of("eE"); |
| 124 | + if (index == s.npos) |
| 125 | + return s; |
| 126 | + int hasSign = (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; |
| 127 | + auto exponentStartIndex = index + 1 + hasSign; |
| 128 | + Json::String normalized = s.substr(0, exponentStartIndex); |
| 129 | + auto indexDigit = s.find_first_not_of('0', exponentStartIndex); |
| 130 | + Json::String exponent = "0"; |
| 131 | + if (indexDigit != s.npos) { // nonzero exponent |
| 132 | + exponent = s.substr(indexDigit); |
142 | 133 | }
|
143 |
| - return s; |
| 134 | + return normalized + exponent; |
144 | 135 | }
|
145 | 136 |
|
146 | 137 | JSONTEST_FIXTURE_LOCAL(ValueTest, checkNormalizeFloatingPointStr) {
|
147 |
| - JSONTEST_ASSERT_STRING_EQUAL("0.0", normalizeFloatingPointStr("0.0")); |
148 |
| - JSONTEST_ASSERT_STRING_EQUAL("0e0", normalizeFloatingPointStr("0e0")); |
149 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234.0", normalizeFloatingPointStr("1234.0")); |
150 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234.0e0", |
151 |
| - normalizeFloatingPointStr("1234.0e0")); |
152 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234.0e-1", |
153 |
| - normalizeFloatingPointStr("1234.0e-1")); |
154 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234.0e+0", |
155 |
| - normalizeFloatingPointStr("1234.0e+0")); |
156 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234.0e+1", |
157 |
| - normalizeFloatingPointStr("1234.0e+001")); |
158 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234e-1", normalizeFloatingPointStr("1234e-1")); |
159 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234e+0", |
160 |
| - normalizeFloatingPointStr("1234e+000")); |
161 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234e+1", |
162 |
| - normalizeFloatingPointStr("1234e+001")); |
163 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234e10", normalizeFloatingPointStr("1234e10")); |
164 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234e10", |
165 |
| - normalizeFloatingPointStr("1234e010")); |
166 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234e+10", |
167 |
| - normalizeFloatingPointStr("1234e+010")); |
168 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234e-10", |
169 |
| - normalizeFloatingPointStr("1234e-010")); |
170 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234e+100", |
171 |
| - normalizeFloatingPointStr("1234e+100")); |
172 |
| - JSONTEST_ASSERT_STRING_EQUAL("1234e-100", |
173 |
| - normalizeFloatingPointStr("1234e-100")); |
| 138 | + struct TestData { |
| 139 | + std::string in; |
| 140 | + std::string out; |
| 141 | + } const testData[] = { |
| 142 | + {"0.0", "0.0"}, |
| 143 | + {"0e0", "0e0"}, |
| 144 | + {"1234.0", "1234.0"}, |
| 145 | + {"1234.0e0", "1234.0e0"}, |
| 146 | + {"1234.0e-1", "1234.0e-1"}, |
| 147 | + {"1234.0e+0", "1234.0e+0"}, |
| 148 | + {"1234.0e+001", "1234.0e+1"}, |
| 149 | + {"1234e-1", "1234e-1"}, |
| 150 | + {"1234e+000", "1234e+0"}, |
| 151 | + {"1234e+001", "1234e+1"}, |
| 152 | + {"1234e10", "1234e10"}, |
| 153 | + {"1234e010", "1234e10"}, |
| 154 | + {"1234e+010", "1234e+10"}, |
| 155 | + {"1234e-010", "1234e-10"}, |
| 156 | + {"1234e+100", "1234e+100"}, |
| 157 | + {"1234e-100", "1234e-100"}, |
| 158 | + }; |
| 159 | + for (const auto& td : testData) { |
| 160 | + JSONTEST_ASSERT_STRING_EQUAL(normalizeFloatingPointStr(td.in), td.out); |
| 161 | + } |
174 | 162 | }
|
175 | 163 |
|
176 | 164 | JSONTEST_FIXTURE_LOCAL(ValueTest, memberCount) {
|
@@ -3145,6 +3133,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) {
|
3145 | 3133 | JSONTEST_ASSERT_EQUAL("property", root);
|
3146 | 3134 | }
|
3147 | 3135 | }
|
| 3136 | + |
3148 | 3137 | JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue107) {
|
3149 | 3138 | // This is interpreted as an int value followed by a colon.
|
3150 | 3139 | Json::CharReaderBuilder b;
|
@@ -3231,124 +3220,66 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, parseComment) {
|
3231 | 3220 | JSONTEST_ASSERT_EQUAL(true, root.asBool());
|
3232 | 3221 | }
|
3233 | 3222 | }
|
3234 |
| -struct CharReaderAllowDropNullTest : JsonTest::TestCase {}; |
3235 | 3223 |
|
3236 |
| -JSONTEST_FIXTURE_LOCAL(CharReaderAllowDropNullTest, issue178) { |
3237 |
| - Json::CharReaderBuilder b; |
3238 |
| - b.settings_["allowDroppedNullPlaceholders"] = true; |
3239 |
| - Json::Value root; |
3240 |
| - Json::String errs; |
3241 |
| - CharReaderPtr reader(b.newCharReader()); |
3242 |
| - { |
3243 |
| - char const doc[] = "{\"a\":,\"b\":true}"; |
3244 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3245 |
| - JSONTEST_ASSERT(ok); |
3246 |
| - JSONTEST_ASSERT_STRING_EQUAL("", errs); |
3247 |
| - JSONTEST_ASSERT_EQUAL(2u, root.size()); |
3248 |
| - JSONTEST_ASSERT_EQUAL(Json::nullValue, root.get("a", true)); |
3249 |
| - } |
3250 |
| - { |
3251 |
| - char const doc[] = "{\"a\":}"; |
3252 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3253 |
| - JSONTEST_ASSERT(ok); |
3254 |
| - JSONTEST_ASSERT_STRING_EQUAL("", errs); |
3255 |
| - JSONTEST_ASSERT_EQUAL(1u, root.size()); |
3256 |
| - JSONTEST_ASSERT_EQUAL(Json::nullValue, root.get("a", true)); |
3257 |
| - } |
3258 |
| - { |
3259 |
| - char const doc[] = "[]"; |
3260 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3261 |
| - JSONTEST_ASSERT(ok); |
3262 |
| - JSONTEST_ASSERT(errs.empty()); |
3263 |
| - JSONTEST_ASSERT_EQUAL(0u, root.size()); |
3264 |
| - JSONTEST_ASSERT_EQUAL(Json::arrayValue, root); |
3265 |
| - } |
3266 |
| - { |
3267 |
| - char const doc[] = "[null]"; |
3268 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3269 |
| - JSONTEST_ASSERT(ok); |
3270 |
| - JSONTEST_ASSERT(errs.empty()); |
3271 |
| - JSONTEST_ASSERT_EQUAL(1u, root.size()); |
3272 |
| - } |
3273 |
| - { |
3274 |
| - char const doc[] = "[,]"; |
3275 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3276 |
| - JSONTEST_ASSERT(ok); |
3277 |
| - JSONTEST_ASSERT_STRING_EQUAL("", errs); |
3278 |
| - JSONTEST_ASSERT_EQUAL(2u, root.size()); |
3279 |
| - } |
3280 |
| - { |
3281 |
| - char const doc[] = "[,,,]"; |
3282 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3283 |
| - JSONTEST_ASSERT(ok); |
3284 |
| - JSONTEST_ASSERT_STRING_EQUAL("", errs); |
3285 |
| - JSONTEST_ASSERT_EQUAL(4u, root.size()); |
3286 |
| - } |
3287 |
| - { |
3288 |
| - char const doc[] = "[null,]"; |
3289 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3290 |
| - JSONTEST_ASSERT(ok); |
3291 |
| - JSONTEST_ASSERT_STRING_EQUAL("", errs); |
3292 |
| - JSONTEST_ASSERT_EQUAL(2u, root.size()); |
3293 |
| - } |
3294 |
| - { |
3295 |
| - char const doc[] = "[,null]"; |
3296 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3297 |
| - JSONTEST_ASSERT(ok); |
3298 |
| - JSONTEST_ASSERT(errs.empty()); |
3299 |
| - JSONTEST_ASSERT_EQUAL(2u, root.size()); |
3300 |
| - } |
3301 |
| - { |
3302 |
| - char const doc[] = "[,,]"; |
3303 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3304 |
| - JSONTEST_ASSERT(ok); |
3305 |
| - JSONTEST_ASSERT_STRING_EQUAL("", errs); |
3306 |
| - JSONTEST_ASSERT_EQUAL(3u, root.size()); |
3307 |
| - } |
3308 |
| - { |
3309 |
| - char const doc[] = "[null,,]"; |
3310 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3311 |
| - JSONTEST_ASSERT(ok); |
3312 |
| - JSONTEST_ASSERT_STRING_EQUAL("", errs); |
3313 |
| - JSONTEST_ASSERT_EQUAL(3u, root.size()); |
3314 |
| - } |
3315 |
| - { |
3316 |
| - char const doc[] = "[,null,]"; |
3317 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3318 |
| - JSONTEST_ASSERT(ok); |
3319 |
| - JSONTEST_ASSERT_STRING_EQUAL("", errs); |
3320 |
| - JSONTEST_ASSERT_EQUAL(3u, root.size()); |
3321 |
| - } |
3322 |
| - { |
3323 |
| - char const doc[] = "[,,null]"; |
3324 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3325 |
| - JSONTEST_ASSERT(ok); |
3326 |
| - JSONTEST_ASSERT(errs.empty()); |
3327 |
| - JSONTEST_ASSERT_EQUAL(3u, root.size()); |
| 3224 | +struct CharReaderAllowDropNullTest : JsonTest::TestCase { |
| 3225 | + using Value = Json::Value; |
| 3226 | + using ValueCheck = std::function<void(const Value&)>; |
| 3227 | + |
| 3228 | + Value nullValue = Value{Json::nullValue}; |
| 3229 | + Value emptyArray = Value{Json::arrayValue}; |
| 3230 | + |
| 3231 | + ValueCheck checkEq(const Value& v) { |
| 3232 | + return [=](const Value& root) { JSONTEST_ASSERT_EQUAL(root, v); }; |
3328 | 3233 | }
|
3329 |
| - { |
3330 |
| - char const doc[] = "[[],,,]"; |
3331 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3332 |
| - JSONTEST_ASSERT(ok); |
3333 |
| - JSONTEST_ASSERT_STRING_EQUAL("", errs); |
3334 |
| - JSONTEST_ASSERT_EQUAL(4u, root.size()); |
3335 |
| - JSONTEST_ASSERT_EQUAL(Json::arrayValue, root[0u]); |
| 3234 | + |
| 3235 | + ValueCheck objGetAnd(std::string idx, ValueCheck f) { |
| 3236 | + return [=](const Value& root) { f(root.get(idx, true)); }; |
3336 | 3237 | }
|
3337 |
| - { |
3338 |
| - char const doc[] = "[,[],,]"; |
3339 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
3340 |
| - JSONTEST_ASSERT(ok); |
3341 |
| - JSONTEST_ASSERT_STRING_EQUAL("", errs); |
3342 |
| - JSONTEST_ASSERT_EQUAL(4u, root.size()); |
3343 |
| - JSONTEST_ASSERT_EQUAL(Json::arrayValue, root[1u]); |
| 3238 | + |
| 3239 | + ValueCheck arrGetAnd(int idx, ValueCheck f) { |
| 3240 | + return [=](const Value& root) { f(root[idx]); }; |
3344 | 3241 | }
|
3345 |
| - { |
3346 |
| - char const doc[] = "[,,,[]]"; |
3347 |
| - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); |
| 3242 | +}; |
| 3243 | + |
| 3244 | +JSONTEST_FIXTURE_LOCAL(CharReaderAllowDropNullTest, issue178) { |
| 3245 | + struct TestSpec { |
| 3246 | + int line; |
| 3247 | + std::string doc; |
| 3248 | + size_t rootSize; |
| 3249 | + ValueCheck onRoot; |
| 3250 | + }; |
| 3251 | + const TestSpec specs[] = { |
| 3252 | + {__LINE__, R"({"a":,"b":true})", 2, objGetAnd("a", checkEq(nullValue))}, |
| 3253 | + {__LINE__, R"({"a":,"b":true})", 2, objGetAnd("a", checkEq(nullValue))}, |
| 3254 | + {__LINE__, R"({"a":})", 1, objGetAnd("a", checkEq(nullValue))}, |
| 3255 | + {__LINE__, "[]", 0, checkEq(emptyArray)}, |
| 3256 | + {__LINE__, "[null]", 1}, |
| 3257 | + {__LINE__, "[,]", 2}, |
| 3258 | + {__LINE__, "[,,,]", 4}, |
| 3259 | + {__LINE__, "[null,]", 2}, |
| 3260 | + {__LINE__, "[,null]", 2}, |
| 3261 | + {__LINE__, "[,,]", 3}, |
| 3262 | + {__LINE__, "[null,,]", 3}, |
| 3263 | + {__LINE__, "[,null,]", 3}, |
| 3264 | + {__LINE__, "[,,null]", 3}, |
| 3265 | + {__LINE__, "[[],,,]", 4, arrGetAnd(0, checkEq(emptyArray))}, |
| 3266 | + {__LINE__, "[,[],,]", 4, arrGetAnd(1, checkEq(emptyArray))}, |
| 3267 | + {__LINE__, "[,,,[]]", 4, arrGetAnd(3, checkEq(emptyArray))}, |
| 3268 | + }; |
| 3269 | + for (const auto& spec : specs) { |
| 3270 | + Json::CharReaderBuilder b; |
| 3271 | + b.settings_["allowDroppedNullPlaceholders"] = true; |
| 3272 | + std::unique_ptr<Json::CharReader> reader(b.newCharReader()); |
| 3273 | + |
| 3274 | + Json::Value root; |
| 3275 | + Json::String errs; |
| 3276 | + bool ok = reader->parse(spec.doc.data(), spec.doc.data() + spec.doc.size(), |
| 3277 | + &root, &errs); |
3348 | 3278 | JSONTEST_ASSERT(ok);
|
3349 |
| - JSONTEST_ASSERT(errs.empty()); |
3350 |
| - JSONTEST_ASSERT_EQUAL(4u, root.size()); |
3351 |
| - JSONTEST_ASSERT_EQUAL(Json::arrayValue, root[3u]); |
| 3279 | + JSONTEST_ASSERT_STRING_EQUAL(errs, ""); |
| 3280 | + if (spec.onRoot) { |
| 3281 | + spec.onRoot(root); |
| 3282 | + } |
3352 | 3283 | }
|
3353 | 3284 | }
|
3354 | 3285 |
|
|
0 commit comments