|
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