proxygen
JsonTest.cpp File Reference
#include <folly/json.h>
#include <iterator>
#include <limits>
#include <folly/portability/GTest.h>

Go to the source code of this file.

Functions

 TEST (Json, Unicode)
 
 TEST (Json, Parse)
 
 TEST (Json, ParseTrailingComma)
 
 TEST (Json, BoolConversion)
 
 TEST (Json, JavascriptSafe)
 
 TEST (Json, Produce)
 
 TEST (Json, JsonEscape)
 
 TEST (Json, JsonNonAsciiEncoding)
 
 TEST (Json, UTF8Retention)
 
 TEST (Json, UTF8EncodeNonAsciiRetention)
 
 TEST (Json, UTF8Validation)
 
 TEST (Json, ParseNonStringKeys)
 
 TEST (Json, ParseDoubleFallback)
 
 TEST (Json, ParseNumbersAsStrings)
 
 TEST (Json, SortKeys)
 
 TEST (Json, PrintTo)
 
 TEST (Json, RecursionLimit)
 
 TEST (Json, ExtraEscapes)
 
 TEST (Json, CharsToUnicodeEscape)
 

Function Documentation

TEST ( Json  ,
Unicode   
)

Definition at line 28 of file JsonTest.cpp.

References EXPECT_EQ, folly::parseJson(), and val.

Referenced by TEST().

28  {
29  auto val = parseJson(u8"\"I \u2665 UTF-8\"");
30  EXPECT_EQ(u8"I \u2665 UTF-8", val.asString());
31  val = parseJson("\"I \\u2665 UTF-8\"");
32  EXPECT_EQ(u8"I \u2665 UTF-8", val.asString());
33  val = parseJson(u8"\"I \U0001D11E playing in G-clef\"");
34  EXPECT_EQ(u8"I \U0001D11E playing in G-clef", val.asString());
35 
36  val = parseJson("\"I \\uD834\\uDD1E playing in G-clef\"");
37  EXPECT_EQ(u8"I \U0001D11E playing in G-clef", val.asString());
38 }
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
double val
Definition: String.cpp:273
TEST ( Json  ,
Parse   
)

Definition at line 40 of file JsonTest.cpp.

References EXPECT_EQ, EXPECT_THROW, EXPECT_TRUE, object, folly::parseJson(), folly::size(), folly::toJson(), and value.

40  {
41  auto num = parseJson("12");
42  EXPECT_TRUE(num.isInt());
43  EXPECT_EQ(num, 12);
44  num = parseJson("12e5");
45  EXPECT_TRUE(num.isDouble());
46  EXPECT_EQ(num, 12e5);
47  auto numAs1 = num.asDouble();
48  EXPECT_EQ(numAs1, 12e5);
49  EXPECT_EQ(num, 12e5);
50  EXPECT_EQ(num, 1200000);
51 
52  auto largeNumber = parseJson("4611686018427387904");
53  EXPECT_TRUE(largeNumber.isInt());
54  EXPECT_EQ(largeNumber, 4611686018427387904L);
55 
56  auto negative = parseJson("-123");
57  EXPECT_EQ(negative, -123);
58 
59  auto bfalse = parseJson("false");
60  auto btrue = parseJson("true");
61  EXPECT_EQ(bfalse, false);
62  EXPECT_EQ(btrue, true);
63 
64  auto null = parseJson("null");
65  EXPECT_TRUE(null == nullptr);
66 
67  auto doub1 = parseJson("12.0");
68  auto doub2 = parseJson("12e2");
69  EXPECT_EQ(doub1, 12.0);
70  EXPECT_EQ(doub2, 12e2);
71  EXPECT_EQ(
72  std::numeric_limits<double>::infinity(),
73  parseJson("Infinity").asDouble());
74  EXPECT_EQ(
75  -std::numeric_limits<double>::infinity(),
76  parseJson("-Infinity").asDouble());
77  EXPECT_TRUE(std::isnan(parseJson("NaN").asDouble()));
78 
79  // case matters
80  EXPECT_THROW(parseJson("infinity"), std::runtime_error);
81  EXPECT_THROW(parseJson("inf"), std::runtime_error);
82  EXPECT_THROW(parseJson("Inf"), std::runtime_error);
83  EXPECT_THROW(parseJson("INF"), std::runtime_error);
84  EXPECT_THROW(parseJson("nan"), std::runtime_error);
85  EXPECT_THROW(parseJson("NAN"), std::runtime_error);
86 
87  auto array = parseJson("[12,false, false , null , [12e4,32, [], 12]]");
88  EXPECT_EQ(array.size(), 5);
89  if (array.size() == 5) {
90  EXPECT_EQ(std::prev(array.end())->size(), 4);
91  }
92 
93  EXPECT_THROW(parseJson("\n[12,\n\nnotvalidjson"), std::runtime_error);
94 
95  EXPECT_THROW(parseJson("12e2e2"), std::runtime_error);
96 
98  parseJson("{\"foo\":12,\"bar\":42} \"something\""), std::runtime_error);
99 
100  // clang-format off
102  ("foo", "bar")
103  ("junk", 12)
104  ("another", 32.2)
105  ("a",
106  dynamic::array(
107  dynamic::object("a", "b")("c", "d"),
108  12.5,
109  "Yo Dawg",
110  dynamic::array("heh"),
111  nullptr));
112  // clang-format on
113 
114  // Print then parse and get the same thing, hopefully.
115  EXPECT_EQ(value, parseJson(toJson(value)));
116 
117  // Test an object with non-string values.
118  dynamic something =
119  parseJson("{\"old_value\":40,\"changed\":true,\"opened\":false}");
120  dynamic expected =
121  dynamic::object("old_value", 40)("changed", true)("opened", false);
122  EXPECT_EQ(something, expected);
123 }
void * object
Definition: AtFork.cpp:32
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
static const char *const value
Definition: Conv.cpp:50
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
std::string toJson(dynamic const &dyn)
Definition: json.cpp:915
TEST ( Json  ,
ParseTrailingComma   
)

Definition at line 125 of file JsonTest.cpp.

References folly::json::serialization_opts::allow_trailing_comma, EXPECT_EQ, EXPECT_THROW, object, folly::pushmi::operators::on, and folly::parseJson().

125  {
127  on.allow_trailing_comma = true;
128  off.allow_trailing_comma = false;
129 
130  dynamic arr = dynamic::array(1, 2);
131  EXPECT_EQ(arr, parseJson("[1, 2]", on));
132  EXPECT_EQ(arr, parseJson("[1, 2,]", on));
133  EXPECT_EQ(arr, parseJson("[1, 2, ]", on));
134  EXPECT_EQ(arr, parseJson("[1, 2 , ]", on));
135  EXPECT_EQ(arr, parseJson("[1, 2 ,]", on));
136  EXPECT_THROW(parseJson("[1, 2,]", off), std::runtime_error);
137 
138  dynamic obj = dynamic::object("a", 1);
139  EXPECT_EQ(obj, parseJson("{\"a\": 1}", on));
140  EXPECT_EQ(obj, parseJson("{\"a\": 1,}", on));
141  EXPECT_EQ(obj, parseJson("{\"a\": 1, }", on));
142  EXPECT_EQ(obj, parseJson("{\"a\": 1 , }", on));
143  EXPECT_EQ(obj, parseJson("{\"a\": 1 ,}", on));
144  EXPECT_THROW(parseJson("{\"a\":1,}", off), std::runtime_error);
145 }
void * object
Definition: AtFork.cpp:32
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
PUSHMI_INLINE_VAR constexpr detail::on_fn on
Definition: on.h:100
TEST ( Json  ,
BoolConversion   
)

Definition at line 147 of file JsonTest.cpp.

References EXPECT_TRUE, and folly::parseJson().

147  {
148  EXPECT_TRUE(parseJson("42").asBool());
149 }
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST ( Json  ,
JavascriptSafe   
)

Definition at line 151 of file JsonTest.cpp.

References EXPECT_ANY_THROW, EXPECT_EQ, int64_t, folly::json::serialization_opts::javascript_safe, folly::json::serialize(), and folly::toJson().

151  {
152  auto badDouble = int64_t((1ULL << 63ULL) + 1);
153  dynamic badDyn = badDouble;
154  EXPECT_EQ(folly::toJson(badDouble), folly::to<std::string>(badDouble));
156  opts.javascript_safe = true;
157  EXPECT_ANY_THROW(folly::json::serialize(badDouble, opts));
158 
159  auto okDouble = int64_t(1ULL << 63ULL);
160  dynamic okDyn = okDouble;
161  EXPECT_EQ(folly::toJson(okDouble), folly::to<std::string>(okDouble));
162 }
#define EXPECT_ANY_THROW(statement)
Definition: gtest.h:1847
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::string serialize(dynamic const &dyn, serialization_opts const &opts)
Definition: json.cpp:621
std::string toJson(dynamic const &dyn)
Definition: json.cpp:915
TEST ( Json  ,
Produce   
)

Definition at line 164 of file JsonTest.cpp.

References folly::json::serialization_opts::allow_nan_inf, EXPECT_EQ, EXPECT_THROW, object, folly::parseJson(), folly::json::serialize(), folly::toJson(), and value.

164  {
165  auto value = parseJson(R"( "f\"oo" )");
166  EXPECT_EQ(toJson(value), R"("f\"oo")");
167  value = parseJson("\"Control code: \001 \002 \x1f\"");
168  EXPECT_EQ(toJson(value), R"("Control code: \u0001 \u0002 \u001f")");
169 
170  // We're not allowed to have non-string keys in json.
171  EXPECT_THROW(
172  toJson(dynamic::object("abc", "xyz")(42.33, "asd")), std::runtime_error);
173 
174  // Check Infinity/Nan
176  opts.allow_nan_inf = true;
177  EXPECT_EQ("Infinity", folly::json::serialize(parseJson("Infinity"), opts));
178  EXPECT_EQ("NaN", folly::json::serialize(parseJson("NaN"), opts));
179 }
void * object
Definition: AtFork.cpp:32
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static const char *const value
Definition: Conv.cpp:50
std::string serialize(dynamic const &dyn, serialization_opts const &opts)
Definition: json.cpp:621
std::string toJson(dynamic const &dyn)
Definition: json.cpp:915
TEST ( Json  ,
JsonEscape   
)

Definition at line 181 of file JsonTest.cpp.

References folly::json::serialization_opts::encode_non_ascii, EXPECT_EQ, i, s, folly::json::serialize(), string, TEST(), and folly::json::serialization_opts::validate_utf8.

181  {
183  EXPECT_EQ(
184  folly::json::serialize("\b\f\n\r\x01\t\\\"/\v\a", opts),
185  R"("\b\f\n\r\u0001\t\\\"/\u000b\u0007")");
186 }
187 
188 TEST(Json, EscapeCornerCases) {
189  // The escaping logic uses some bitwise operations to determine
190  // which bytes need escaping 8 bytes at a time. Test that this logic
191  // is correct regardless of positions by planting 2 characters that
192  // may need escaping at each possible position and checking the
193  // result, for varying string lengths.
194 
196  opts.validate_utf8 = true;
197 
198  std::string s;
199  std::string expected;
200  for (bool ascii : {true, false}) {
201  opts.encode_non_ascii = ascii;
202 
203  for (size_t len = 2; len < 32; ++len) {
204  for (size_t i = 0; i < len; ++i) {
205  for (size_t j = 0; j < len; ++j) {
206  if (i == j) {
207  continue;
208  }
209 
210  s.clear();
211  expected.clear();
212 
213  expected.push_back('"');
214  for (size_t pos = 0; pos < len; ++pos) {
215  if (pos == i) {
216  s.push_back('\\');
217  expected.append("\\\\");
218  } else if (pos == j) {
219  s.append("\xe2\x82\xac");
220  expected.append(ascii ? "\\u20ac" : "\xe2\x82\xac");
221  } else {
222  s.push_back('x');
223  expected.push_back('x');
224  }
225  }
226  expected.push_back('"');
227 
228  EXPECT_EQ(folly::json::serialize(s, opts), expected) << ascii;
229  }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
const char * string
Definition: Conv.cpp:212
TEST(Json, Unicode)
Definition: JsonTest.cpp:28
static set< string > s
std::string serialize(dynamic const &dyn, serialization_opts const &opts)
Definition: json.cpp:621
TEST ( Json  ,
JsonNonAsciiEncoding   
)

Definition at line 235 of file JsonTest.cpp.

References folly::json::serialization_opts::encode_non_ascii, EXPECT_ANY_THROW, EXPECT_EQ, and folly::json::serialize().

235  {
237  opts.encode_non_ascii = true;
238 
239  // simple tests
240  EXPECT_EQ(folly::json::serialize("\x1f", opts), R"("\u001f")");
241  EXPECT_EQ(folly::json::serialize("\xc2\xa2", opts), R"("\u00a2")");
242  EXPECT_EQ(folly::json::serialize("\xe2\x82\xac", opts), R"("\u20ac")");
243 
244  // multiple unicode encodings
245  EXPECT_EQ(
246  folly::json::serialize("\x1f\xe2\x82\xac", opts), R"("\u001f\u20ac")");
247  EXPECT_EQ(
248  folly::json::serialize("\x1f\xc2\xa2\xe2\x82\xac", opts),
249  R"("\u001f\u00a2\u20ac")");
250  EXPECT_EQ(
251  folly::json::serialize("\xc2\x80\xef\xbf\xbf", opts),
252  R"("\u0080\uffff")");
253  EXPECT_EQ(
254  folly::json::serialize("\xe0\xa0\x80\xdf\xbf", opts),
255  R"("\u0800\u07ff")");
256 
257  // first possible sequence of a certain length
258  EXPECT_EQ(folly::json::serialize("\xc2\x80", opts), R"("\u0080")");
259  EXPECT_EQ(folly::json::serialize("\xe0\xa0\x80", opts), R"("\u0800")");
260 
261  // last possible sequence of a certain length
262  EXPECT_EQ(folly::json::serialize("\xdf\xbf", opts), R"("\u07ff")");
263  EXPECT_EQ(folly::json::serialize("\xef\xbf\xbf", opts), R"("\uffff")");
264 
265  // other boundary conditions
266  EXPECT_EQ(folly::json::serialize("\xed\x9f\xbf", opts), R"("\ud7ff")");
267  EXPECT_EQ(folly::json::serialize("\xee\x80\x80", opts), R"("\ue000")");
268  EXPECT_EQ(folly::json::serialize("\xef\xbf\xbd", opts), R"("\ufffd")");
269 
270  // incomplete sequences
271  EXPECT_ANY_THROW(folly::json::serialize("a\xed\x9f", opts));
272  EXPECT_ANY_THROW(folly::json::serialize("b\xee\x80", opts));
273  EXPECT_ANY_THROW(folly::json::serialize("c\xef\xbf", opts));
274 
275  // impossible bytes
278 
279  // Sample overlong sequences
280  EXPECT_ANY_THROW(folly::json::serialize("\xc0\xaf", opts));
281  EXPECT_ANY_THROW(folly::json::serialize("\xe0\x80\xaf", opts));
282 
283  // Maximum overlong sequences
284  EXPECT_ANY_THROW(folly::json::serialize("\xc1\xbf", opts));
285  EXPECT_ANY_THROW(folly::json::serialize("\x30\x9f\xbf", opts));
286 
287  // illegal code positions
288  EXPECT_ANY_THROW(folly::json::serialize("\xed\xa0\x80", opts));
289  EXPECT_ANY_THROW(folly::json::serialize("\xed\xbf\xbf", opts));
290 
291  // Overlong representation of NUL character
292  EXPECT_ANY_THROW(folly::json::serialize("\xc0\x80", opts));
293  EXPECT_ANY_THROW(folly::json::serialize("\xe0\x80\x80", opts));
294 
295  // Allow 4 byte encodings, escape using 2 UTF-16 surrogate pairs.
296  // "\xf0\x9f\x8d\x80" is Unicode Character 'FOUR LEAF CLOVER' (U+1F340)
297  // >>> json.dumps({"a": u"\U0001F340"})
298  // '{"a": "\\ud83c\\udf40"}'
299  EXPECT_EQ(
300  folly::json::serialize("\xf0\x9f\x8d\x80", opts), R"("\ud83c\udf40")");
301  // Longer than 4 byte encodings
302  EXPECT_ANY_THROW(folly::json::serialize("\xed\xaf\xbf\xed\xbf\xbf", opts));
303 }
#define EXPECT_ANY_THROW(statement)
Definition: gtest.h:1847
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::string serialize(dynamic const &dyn, serialization_opts const &opts)
Definition: json.cpp:621
TEST ( Json  ,
UTF8Retention   
)

Definition at line 305 of file JsonTest.cpp.

References folly::dynamic::asString(), EXPECT_EQ, gmock_output_test::output, folly::parseJson(), string, and folly::toJson().

305  {
306  // test retention with valid utf8 strings
307  std::string input = u8"\u2665";
308  std::string jsonInput = folly::toJson(input);
310  std::string jsonOutput = folly::toJson(output);
311 
312  EXPECT_EQ(input, output);
313  EXPECT_EQ(jsonInput, jsonOutput);
314 
315  // test retention with invalid utf8 - note that non-ascii chars are retained
316  // as is, and no unicode encoding is attempted so no exception is thrown.
317  EXPECT_EQ(
318  folly::toJson("a\xe0\xa0\x80z\xc0\x80"), "\"a\xe0\xa0\x80z\xc0\x80\"");
319 }
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::string asString() const
Definition: dynamic-inl.h:518
const char * string
Definition: Conv.cpp:212
std::string toJson(dynamic const &dyn)
Definition: json.cpp:915
TEST ( Json  ,
UTF8EncodeNonAsciiRetention   
)

Definition at line 321 of file JsonTest.cpp.

References folly::dynamic::asString(), folly::json::serialization_opts::encode_non_ascii, EXPECT_ANY_THROW, EXPECT_EQ, gmock_output_test::output, folly::parseJson(), folly::json::serialize(), and string.

321  {
323  opts.encode_non_ascii = true;
324 
325  // test encode_non_ascii valid utf8 strings
326  std::string input = u8"\u2665";
327  std::string jsonInput = folly::json::serialize(input, opts);
329  std::string jsonOutput = folly::json::serialize(output, opts);
330 
331  EXPECT_EQ(input, output);
332  EXPECT_EQ(jsonInput, jsonOutput);
333 
334  // test encode_non_ascii with invalid utf8 - note that an attempt to encode
335  // non-ascii to unicode will result is a utf8 validation and throw exceptions.
336  EXPECT_ANY_THROW(folly::json::serialize("a\xe0\xa0\x80z\xc0\x80", opts));
337  EXPECT_ANY_THROW(folly::json::serialize("a\xe0\xa0\x80z\xe0\x80\x80", opts));
338 }
#define EXPECT_ANY_THROW(statement)
Definition: gtest.h:1847
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::string asString() const
Definition: dynamic-inl.h:518
const char * string
Definition: Conv.cpp:212
std::string serialize(dynamic const &dyn, serialization_opts const &opts)
Definition: json.cpp:621
TEST ( Json  ,
UTF8Validation   
)

Definition at line 340 of file JsonTest.cpp.

References folly::json::serialization_opts::encode_non_ascii, EXPECT_ANY_THROW, EXPECT_EQ, folly::json::serialize(), folly::json::serialization_opts::skip_invalid_utf8, and folly::json::serialization_opts::validate_utf8.

340  {
342  opts.validate_utf8 = true;
343 
344  // test validate_utf8 valid utf8 strings - note that we only validate the
345  // for utf8 but don't encode non-ascii to unicode so they are retained as is.
346  EXPECT_EQ(folly::json::serialize("a\xc2\x80z", opts), "\"a\xc2\x80z\"");
347  EXPECT_EQ(
348  folly::json::serialize("a\xe0\xa0\x80z", opts), "\"a\xe0\xa0\x80z\"");
349  EXPECT_EQ(
350  folly::json::serialize("a\xe0\xa0\x80m\xc2\x80z", opts),
351  "\"a\xe0\xa0\x80m\xc2\x80z\"");
352 
353  // test validate_utf8 with invalid utf8
354  EXPECT_ANY_THROW(folly::json::serialize("a\xe0\xa0\x80z\xc0\x80", opts));
355  EXPECT_ANY_THROW(folly::json::serialize("a\xe0\xa0\x80z\xe0\x80\x80", opts));
356 
357  opts.skip_invalid_utf8 = true;
358  EXPECT_EQ(
359  folly::json::serialize("a\xe0\xa0\x80z\xc0\x80", opts),
360  u8"\"a\xe0\xa0\x80z\ufffd\ufffd\"");
361  EXPECT_EQ(
362  folly::json::serialize("a\xe0\xa0\x80z\xc0\x80\x80", opts),
363  u8"\"a\xe0\xa0\x80z\ufffd\ufffd\ufffd\"");
364  EXPECT_EQ(
365  folly::json::serialize("z\xc0\x80z\xe0\xa0\x80", opts),
366  u8"\"z\ufffd\ufffdz\xe0\xa0\x80\"");
367 
368  opts.encode_non_ascii = true;
369  EXPECT_EQ(
370  folly::json::serialize("a\xe0\xa0\x80z\xc0\x80", opts),
371  "\"a\\u0800z\\ufffd\\ufffd\"");
372  EXPECT_EQ(
373  folly::json::serialize("a\xe0\xa0\x80z\xc0\x80\x80", opts),
374  "\"a\\u0800z\\ufffd\\ufffd\\ufffd\"");
375  EXPECT_EQ(
376  folly::json::serialize("z\xc0\x80z\xe0\xa0\x80", opts),
377  "\"z\\ufffd\\ufffdz\\u0800\"");
378 }
#define EXPECT_ANY_THROW(statement)
Definition: gtest.h:1847
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::string serialize(dynamic const &dyn, serialization_opts const &opts)
Definition: json.cpp:621
TEST ( Json  ,
ParseNonStringKeys   
)

Definition at line 380 of file JsonTest.cpp.

References folly::json::serialization_opts::allow_non_string_keys, folly::test::begin(), EXPECT_EQ, EXPECT_THROW, folly::gen::first, folly::parseJson(), and val.

380  {
381  // test string keys
382  EXPECT_EQ("a", parseJson("{\"a\":[]}").items().begin()->first.asString());
383 
384  // check that we don't allow non-string keys as this violates the
385  // strict JSON spec (though it is emitted by the output of
386  // folly::dynamic with operator <<).
387  EXPECT_THROW(parseJson("{1:[]}"), std::runtime_error);
388 
389  // check that we can parse colloquial JSON if the option is set
391  opts.allow_non_string_keys = true;
392 
393  auto val = parseJson("{1:[]}", opts);
394  EXPECT_EQ(1, val.items().begin()->first.asInt());
395 
396  // test we can still read in strings
397  auto sval = parseJson("{\"a\":[]}", opts);
398  EXPECT_EQ("a", sval.items().begin()->first.asString());
399 
400  // test we can read in doubles
401  auto dval = parseJson("{1.5:[]}", opts);
402  EXPECT_EQ(1.5, dval.items().begin()->first.asDouble());
403 }
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
auto begin(TestAdlIterable &instance)
Definition: ForeachTest.cpp:56
double val
Definition: String.cpp:273
constexpr detail::First first
Definition: Base-inl.h:2553
TEST ( Json  ,
ParseDoubleFallback   
)

Definition at line 405 of file JsonTest.cpp.

References folly::test::begin(), folly::json::serialization_opts::double_fallback, EXPECT_EQ, EXPECT_THROW, max, min, folly::parseJson(), and folly::toJson().

405  {
406  // default behavior
407  EXPECT_THROW(
408  parseJson("{\"a\":847605071342477600000000000000}"), std::range_error);
409  EXPECT_THROW(parseJson("{\"a\":-9223372036854775809}"), std::range_error);
410  EXPECT_THROW(parseJson("{\"a\":9223372036854775808}"), std::range_error);
411  EXPECT_EQ(
413  parseJson("{\"a\":-9223372036854775808}")
414  .items()
415  .begin()
416  ->second.asInt());
417  EXPECT_EQ(
419  parseJson("{\"a\":9223372036854775807}").items().begin()->second.asInt());
420  // with double_fallback
422  opts.double_fallback = true;
423  EXPECT_EQ(
424  847605071342477600000000000000.0,
425  parseJson("{\"a\":847605071342477600000000000000}", opts)
426  .items()
427  .begin()
428  ->second.asDouble());
429  EXPECT_EQ(
430  847605071342477600000000000000.0,
431  parseJson("{\"a\": 847605071342477600000000000000}", opts)
432  .items()
433  .begin()
434  ->second.asDouble());
435  EXPECT_EQ(
436  847605071342477600000000000000.0,
437  parseJson("{\"a\":847605071342477600000000000000 }", opts)
438  .items()
439  .begin()
440  ->second.asDouble());
441  EXPECT_EQ(
442  847605071342477600000000000000.0,
443  parseJson("{\"a\": 847605071342477600000000000000 }", opts)
444  .items()
445  .begin()
446  ->second.asDouble());
447  EXPECT_EQ(
449  parseJson("{\"a\":-9223372036854775808}", opts)
450  .items()
451  .begin()
452  ->second.asInt());
453  EXPECT_EQ(
455  parseJson("{\"a\":9223372036854775807}", opts)
456  .items()
457  .begin()
458  ->second.asInt());
459  // show that some precision gets lost
460  EXPECT_EQ(
461  847605071342477612345678900000.0,
462  parseJson("{\"a\":847605071342477612345678912345}", opts)
463  .items()
464  .begin()
465  ->second.asDouble());
466  EXPECT_EQ(
467  toJson(parseJson(R"({"a":-9223372036854775808})", opts)),
468  R"({"a":-9223372036854775808})");
469 }
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
LogLevel max
Definition: LogLevel.cpp:31
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
auto begin(TestAdlIterable &instance)
Definition: ForeachTest.cpp:56
LogLevel min
Definition: LogLevel.cpp:30
std::string toJson(dynamic const &dyn)
Definition: json.cpp:915
TEST ( Json  ,
ParseNumbersAsStrings   
)

Definition at line 471 of file JsonTest.cpp.

References folly::dynamic::asString(), EXPECT_EQ, EXPECT_THROW, number, parse(), folly::json::serialization_opts::parse_numbers_as_strings, folly::parseJson(), and string.

471  {
473  opts.parse_numbers_as_strings = true;
474  auto parse = [&](std::string number) {
475  return parseJson(number, opts).asString();
476  };
477 
478  EXPECT_EQ("0", parse("0"));
479  EXPECT_EQ("1234", parse("1234"));
480  EXPECT_EQ("3.00", parse("3.00"));
481  EXPECT_EQ("3.14", parse("3.14"));
482  EXPECT_EQ("0.1234", parse("0.1234"));
483  EXPECT_EQ("0.0", parse("0.0"));
484  EXPECT_EQ(
485  "46845131213548676854213265486468451312135486768542132",
486  parse("46845131213548676854213265486468451312135486768542132"));
487  EXPECT_EQ(
488  "-468451312135486768542132654864684513121354867685.5e4",
489  parse("-468451312135486768542132654864684513121354867685.5e4"));
490  EXPECT_EQ("6.62607004e-34", parse("6.62607004e-34"));
491  EXPECT_EQ("6.62607004E+34", parse("6.62607004E+34"));
492  EXPECT_EQ("Infinity", parse("Infinity"));
493  EXPECT_EQ("-Infinity", parse("-Infinity"));
494  EXPECT_EQ("NaN", parse("NaN"));
495 
496  EXPECT_THROW(parse("ThisIsWrong"), std::runtime_error);
497  EXPECT_THROW(parse("34-2"), std::runtime_error);
498  EXPECT_THROW(parse(""), std::runtime_error);
499  EXPECT_THROW(parse("-"), std::runtime_error);
500  EXPECT_THROW(parse("34-e2"), std::runtime_error);
501  EXPECT_THROW(parse("34e2.4"), std::runtime_error);
502  EXPECT_THROW(parse("infinity"), std::runtime_error);
503  EXPECT_THROW(parse("nan"), std::runtime_error);
504 }
size_t parse(const char *buf, size_t len)
Definition: test.c:1591
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
int number
std::string asString() const
Definition: dynamic-inl.h:518
const char * string
Definition: Conv.cpp:212
TEST ( Json  ,
SortKeys   
)

Definition at line 506 of file JsonTest.cpp.

References a, b, EXPECT_EQ, EXPECT_NE, object, folly::parseJson(), folly::json::serialize(), folly::json::serialization_opts::sort_keys, folly::json::serialization_opts::sort_keys_by, string, and value.

506  {
507  folly::json::serialization_opts opts_on, opts_off, opts_custom_sort;
508  opts_on.sort_keys = true;
509  opts_off.sort_keys = false;
510 
511  opts_custom_sort.sort_keys = false; // should not be required
512  opts_custom_sort.sort_keys_by = [](folly::dynamic const& a,
513  folly::dynamic const& b) {
514  // just an inverse sort
515  return b < a;
516  };
517 
518  // clang-format off
520  ("foo", "bar")
521  ("junk", 12)
522  ("another", 32.2)
523  ("a",
524  dynamic::array(
525  dynamic::object("a", "b")("c", "d"),
526  12.5,
527  "Yo Dawg",
528  dynamic::array("heh"),
529  nullptr));
530  // clang-format on
531 
532  std::string sorted_keys =
533  R"({"a":[{"a":"b","c":"d"},12.5,"Yo Dawg",["heh"],null],)"
534  R"("another":32.2,"foo":"bar","junk":12})";
535 
536  std::string inverse_sorted_keys =
537  R"({"junk":12,"foo":"bar","another":32.2,)"
538  R"("a":[{"c":"d","a":"b"},12.5,"Yo Dawg",["heh"],null]})";
539 
540  EXPECT_EQ(value, parseJson(folly::json::serialize(value, opts_on)));
541  EXPECT_EQ(value, parseJson(folly::json::serialize(value, opts_off)));
542  EXPECT_EQ(value, parseJson(folly::json::serialize(value, opts_custom_sort)));
543 
544  EXPECT_EQ(sorted_keys, folly::json::serialize(value, opts_on));
545  EXPECT_NE(sorted_keys, folly::json::serialize(value, opts_off));
546  EXPECT_EQ(
547  inverse_sorted_keys, folly::json::serialize(value, opts_custom_sort));
548 }
void * object
Definition: AtFork.cpp:32
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
char b
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
char a
static const char *const value
Definition: Conv.cpp:50
Function< bool(dynamic const &, dynamic const &) const > sort_keys_by
Definition: json.h:108
const char * string
Definition: Conv.cpp:212
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
std::string serialize(dynamic const &dyn, serialization_opts const &opts)
Definition: json.cpp:621
TEST ( Json  ,
PrintTo   
)

Definition at line 550 of file JsonTest.cpp.

References EXPECT_EQ, object, testing::internal::PrintTo(), string, and value.

550  {
551  std::ostringstream oss;
552 
553  // clang-format off
555  ("foo", "bar")
556  ("junk", 12)
557  ("another", 32.2)
558  (true, false) // include non-string keys
559  (false, true)
560  (2, 3)
561  (0, 1)
562  (1, 2)
563  (1.5, 2.25)
564  (0.5, 0.25)
565  (0, 1)
566  (1, 2)
567  ("a",
568  dynamic::array(
569  dynamic::object("a", "b")
570  ("c", "d"),
571  12.5,
572  "Yo Dawg",
573  dynamic::array("heh"),
574  nullptr
575  )
576  )
577  ;
578  // clang-format on
579 
580  std::string expected =
581  R"({
582  false: true,
583  true: false,
584  0.5: 0.25,
585  1.5: 2.25,
586  0: 1,
587  1: 2,
588  2: 3,
589  "a": [
590  {
591  "a": "b",
592  "c": "d"
593  },
594  12.5,
595  "Yo Dawg",
596  [
597  "heh"
598  ],
599  null
600  ],
601  "another": 32.2,
602  "foo": "bar",
603  "junk": 12
604 })";
605  PrintTo(value, &oss);
606  EXPECT_EQ(expected, oss.str());
607 }
void * object
Definition: AtFork.cpp:32
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
static const char *const value
Definition: Conv.cpp:50
const char * string
Definition: Conv.cpp:212
void PrintTo(const ReferenceWrapper< T > &ref,::std::ostream *os)
TEST ( Json  ,
RecursionLimit   
)

Definition at line 609 of file JsonTest.cpp.

References EXPECT_ANY_THROW, i, folly::parseJson(), folly::json::serialization_opts::recursion_limit, and string.

609  {
610  std::string in;
611  for (int i = 0; i < 1000; i++) {
612  in.append("{\"x\":");
613  }
614  in.append("\"hi\"");
615  for (int i = 0; i < 1000; i++) {
616  in.append("}");
617  }
619 
620  folly::json::serialization_opts opts_high_recursion_limit;
621  opts_high_recursion_limit.recursion_limit = 10000;
622  parseJson(in, opts_high_recursion_limit);
623 }
#define EXPECT_ANY_THROW(statement)
Definition: gtest.h:1847
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
unsigned int recursion_limit
Definition: json.h:130
const char * string
Definition: Conv.cpp:212
TEST ( Json  ,
ExtraEscapes   
)

Definition at line 625 of file JsonTest.cpp.

References folly::json::buildExtraAsciiToEscapeBitmap(), EXPECT_EQ, folly::json::serialization_opts::extra_ascii_to_escape_bitmap, object, folly::parseJson(), and folly::json::serialize().

625  {
627  dynamic in = dynamic::object("a", "<foo@bar%baz?>");
628 
629  // Only in second index, only first bit of that index.
632  auto serialized = folly::json::serialize(in, opts);
633  EXPECT_EQ("{\"a\":\"<foo\\u0040bar%baz?>\"}", serialized);
634  EXPECT_EQ(in, folly::parseJson(serialized));
635 
636  // Only last bit.
639  serialized = folly::json::serialize(in, opts);
640  EXPECT_EQ("{\"a\":\"<foo@bar%baz\\u003f>\"}", serialized);
641  EXPECT_EQ(in, folly::parseJson(serialized));
642 
643  // Multiple bits.
646  serialized = folly::json::serialize(in, opts);
647  EXPECT_EQ("{\"a\":\"\\u003cfoo\\u0040bar\\u0025baz\\u003f>\"}", serialized);
648  EXPECT_EQ(in, folly::parseJson(serialized));
649 
650  // Non-ASCII
651  in = dynamic::object("a", "a\xe0\xa0\x80z\xc0\x80");
654  serialized = folly::json::serialize(in, opts);
655  EXPECT_EQ("{\"a\":\"a\xe0\xa0\x80z\xc0\x80\"}", serialized);
656  EXPECT_EQ(in, folly::parseJson(serialized));
657 }
void * object
Definition: AtFork.cpp:32
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::array< uint64_t, 2 > buildExtraAsciiToEscapeBitmap(StringPiece chars)
Definition: json.cpp:611
std::array< uint64_t, 2 > extra_ascii_to_escape_bitmap
Definition: json.h:137
std::string serialize(dynamic const &dyn, serialization_opts const &opts)
Definition: json.cpp:621
TEST ( Json  ,
CharsToUnicodeEscape   
)

Definition at line 659 of file JsonTest.cpp.

References folly::json::buildExtraAsciiToEscapeBitmap(), EXPECT_EQ, and uint64_t.

659  {
660  auto testPair = [](std::array<uint64_t, 2> arr, uint64_t zero, uint64_t one) {
661  EXPECT_EQ(zero, arr[0]);
662  EXPECT_EQ(one, arr[1]);
663  };
664 
665  testPair(folly::json::buildExtraAsciiToEscapeBitmap(""), 0, 0);
666 
667  // ?=63
668  testPair(folly::json::buildExtraAsciiToEscapeBitmap("?"), (1UL << 63), 0);
669 
670  // @=64
671  testPair(
672  folly::json::buildExtraAsciiToEscapeBitmap("@"), 0, (1UL << (64 - 64)));
673 
674  testPair(
676  (1UL << 63),
677  (1UL << (64 - 64)));
678  testPair(
680  (1UL << 63),
681  (1UL << (64 - 64)));
682 
683  // duplicates
684  testPair(
686  (1UL << 63),
687  (1UL << (64 - 64)));
688 
689  // ?=63, @=64, $=36
690  testPair(
692  (1UL << 63) | (1UL << 36),
693  (1UL << (64 - 64)));
694 
695  // ?=63, $=36, @=64, !=33
696  testPair(
698  (1UL << 63) | (1UL << 36) | (1UL << 33),
699  (1UL << (64 - 64)));
700 
701  // ?=63, $=36, @=64, !=33, ]=93
702  testPair(
704  (1UL << 63) | (1UL << 36) | (1UL << 33),
705  (1UL << (64 - 64)) | (1UL << (93 - 64)));
706 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
std::array< uint64_t, 2 > buildExtraAsciiToEscapeBitmap(StringPiece chars)
Definition: json.cpp:611