proxygen
DynamicTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <folly/dynamic.h>
18 
19 #include <folly/Range.h>
20 #include <folly/json.h>
22 
23 #include <iterator>
24 
25 using folly::dynamic;
26 using folly::StringPiece;
27 
28 TEST(Dynamic, Default) {
29  dynamic obj;
30  EXPECT_TRUE(obj.isNull());
31 }
32 
33 TEST(Dynamic, ObjectBasics) {
34  dynamic obj = dynamic::object("a", false);
35  EXPECT_EQ(obj.at("a"), false);
36  EXPECT_EQ(obj.size(), 1);
37  obj.insert("a", true);
38 
39  dynamic key{"a"};
40  folly::StringPiece sp{"a"};
41  std::string s{"a"};
42 
43  EXPECT_EQ(obj.size(), 1);
44  EXPECT_EQ(obj.at("a"), true);
45  EXPECT_EQ(obj.at(sp), true);
46  EXPECT_EQ(obj.at(key), true);
47 
48  obj.at(sp) = nullptr;
49  EXPECT_EQ(obj.size(), 1);
50  EXPECT_TRUE(obj.at(s) == nullptr);
51 
52  obj["a"] = 12;
53  EXPECT_EQ(obj[sp], 12);
54  obj[key] = "foo";
55  EXPECT_EQ(obj["a"], "foo");
56  (void)obj["b"];
57  EXPECT_EQ(obj.size(), 2);
58 
59  obj.erase("a");
60  EXPECT_TRUE(obj.find(sp) == obj.items().end());
61  obj.erase("b");
62  EXPECT_EQ(obj.size(), 0);
63 
64  dynamic newObject = dynamic::object;
65 
66  newObject["z"] = 12;
67  EXPECT_EQ(newObject.size(), 1);
68  newObject["a"] = true;
69  EXPECT_EQ(newObject.size(), 2);
70 
71  EXPECT_EQ(*newObject.keys().begin(), newObject.items().begin()->first);
72  EXPECT_EQ(*newObject.values().begin(), newObject.items().begin()->second);
73  std::vector<std::pair<std::string, dynamic>> found;
74  found.emplace_back(
75  newObject.keys().begin()->asString(), *newObject.values().begin());
76 
77  EXPECT_EQ(
78  *std::next(newObject.keys().begin()),
79  std::next(newObject.items().begin())->first);
80  EXPECT_EQ(
81  *std::next(newObject.values().begin()),
82  std::next(newObject.items().begin())->second);
83  found.emplace_back(
84  std::next(newObject.keys().begin())->asString(),
85  *std::next(newObject.values().begin()));
86 
87  std::sort(found.begin(), found.end());
88 
89  EXPECT_EQ("a", found[0].first);
90  EXPECT_TRUE(found[0].second.asBool());
91 
92  EXPECT_EQ("z", found[1].first);
93  EXPECT_EQ(12, found[1].second.asInt());
94 
95  dynamic obj2 = dynamic::object;
96  EXPECT_TRUE(obj2.isObject());
97 
98  dynamic d3 = nullptr;
99  EXPECT_TRUE(d3 == nullptr);
100  d3 = dynamic::object;
101  EXPECT_TRUE(d3.isObject());
102  d3["foo"] = dynamic::array(1, 2, 3);
103  EXPECT_EQ(d3.count("foo"), 1);
104 
105  d3[123] = 321;
106  EXPECT_EQ(d3.at(123), 321);
107 
108  d3["123"] = 42;
109  EXPECT_EQ(d3.at("123"), 42);
110  EXPECT_EQ(d3.at(123), 321);
111 
112  dynamic objInsert = folly::dynamic::object();
113  dynamic objA = folly::dynamic::object("1", "2");
114  dynamic objB = folly::dynamic::object("1", "2");
115 
116  objInsert.insert("1", std::move(objA));
117  objInsert.insert("1", std::move(objB));
118 
119  EXPECT_EQ(objInsert.find("1")->second.size(), 1);
120 
121  // Looking up objects as keys
122  // clang-format off
123  dynamic objDefinedInOneOrder = folly::dynamic::object
124  ("bar", "987")
125  ("baz", folly::dynamic::array(1, 2, 3))
126  ("foo2", folly::dynamic::object("1", "2"));
127  dynamic sameObjInDifferentOrder = folly::dynamic::object
128  ("bar", "987")
129  ("foo2", folly::dynamic::object("1", "2"))
130  ("baz", folly::dynamic::array(1, 2, 3));
131  // clang-format on
132 
133  newObject[objDefinedInOneOrder] = 12;
134  EXPECT_EQ(newObject.at(objDefinedInOneOrder).getInt(), 12);
135  EXPECT_EQ(newObject.at(sameObjInDifferentOrder).getInt(), 12);
136 
137  // Merge two objects
138  dynamic origMergeObj1 = folly::dynamic::object();
139  // clang-format off
140  dynamic mergeObj1 = origMergeObj1 = folly::dynamic::object
141  ("key1", "value1")
142  ("key2", "value2");
143  dynamic mergeObj2 = folly::dynamic::object
144  ("key2", "value3")
145  ("key3", "value4");
146  // clang-format on
147 
148  // Merged object where we prefer the values in mergeObj2
149  // clang-format off
150  dynamic combinedPreferObj2 = folly::dynamic::object
151  ("key1", "value1")
152  ("key2", "value3")
153  ("key3", "value4");
154  // clang-format on
155 
156  // Merged object where we prefer the values in mergeObj1
157  // clang-format off
158  dynamic combinedPreferObj1 = folly::dynamic::object
159  ("key1", "value1")
160  ("key2", "value2")
161  ("key3", "value4");
162  // clang-format on
163 
164  auto newMergeObj = dynamic::merge(mergeObj1, mergeObj2);
165  EXPECT_EQ(newMergeObj, combinedPreferObj2);
166  EXPECT_EQ(mergeObj1, origMergeObj1); // mergeObj1 should be unchanged
167 
168  mergeObj1.update(mergeObj2);
169  EXPECT_EQ(mergeObj1, combinedPreferObj2);
170  dynamic arr = dynamic::array(1, 2, 3, 4, 5, 6);
171  EXPECT_THROW(mergeObj1.update(arr), std::exception);
172 
173  mergeObj1 = origMergeObj1; // reset it
174  mergeObj1.update_missing(mergeObj2);
175  EXPECT_EQ(mergeObj1, combinedPreferObj1);
176 }
177 
178 namespace {
179 
180 struct StaticStrings {
181  static constexpr auto kA = "a";
182  static constexpr const char* kB = "b";
183  static const folly::StringPiece kFoo;
184  static const std::string kBar;
185 };
186 /* static */ const folly::StringPiece StaticStrings::kFoo{"foo"};
187 /* static */ const std::string StaticStrings::kBar{"bar"};
188 
189 } // namespace
190 
191 TEST(Dynamic, ObjectHeterogeneousAccess) {
192  dynamic empty;
193  dynamic foo{"foo"};
194  const char* a = "a";
195  StringPiece sp{"a"};
196  std::string str{"a"};
197  dynamic bar{"bar"};
198  const char* b = "b";
199 
200  dynamic obj = dynamic::object("a", 123)(empty, 456)(foo, 789);
201 
202  // at()
203  EXPECT_EQ(obj.at(empty), 456);
204  EXPECT_EQ(obj.at(nullptr), 456);
205  EXPECT_EQ(obj.at(foo), 789);
206 
207  EXPECT_EQ(obj.at(a), 123);
208  EXPECT_EQ(obj.at(StaticStrings::kA), 123);
209  EXPECT_EQ(obj.at("a"), 123);
210 
211  EXPECT_EQ(obj.at(sp), 123);
212  EXPECT_EQ(obj.at(StringPiece{"a"}), 123);
213  EXPECT_EQ(obj.at(StaticStrings::kFoo), 789);
214 
215  EXPECT_EQ(obj.at(std::string{"a"}), 123);
216  EXPECT_EQ(obj.at(str), 123);
217 
218  EXPECT_THROW(obj.at(b), std::out_of_range);
219  EXPECT_THROW(obj.at(StringPiece{b}), std::out_of_range);
220  EXPECT_THROW(obj.at(StaticStrings::kBar), std::out_of_range);
221 
222  // get_ptr()
223  EXPECT_NE(obj.get_ptr(empty), nullptr);
224  EXPECT_EQ(*obj.get_ptr(empty), 456);
225  EXPECT_NE(obj.get_ptr(nullptr), nullptr);
226  EXPECT_EQ(*obj.get_ptr(nullptr), 456);
227  EXPECT_NE(obj.get_ptr(foo), nullptr);
228  EXPECT_EQ(*obj.get_ptr(foo), 789);
229 
230  EXPECT_NE(obj.get_ptr(a), nullptr);
231  EXPECT_EQ(*obj.get_ptr(a), 123);
232  EXPECT_NE(obj.get_ptr(StaticStrings::kA), nullptr);
233  EXPECT_EQ(*obj.get_ptr(StaticStrings::kA), 123);
234  EXPECT_NE(obj.get_ptr("a"), nullptr);
235  EXPECT_EQ(*obj.get_ptr("a"), 123);
236 
237  EXPECT_NE(obj.get_ptr(sp), nullptr);
238  EXPECT_EQ(*obj.get_ptr(sp), 123);
239  EXPECT_NE(obj.get_ptr(StringPiece{"a"}), nullptr);
240  EXPECT_EQ(*obj.get_ptr(StringPiece{"a"}), 123);
241  EXPECT_NE(obj.get_ptr(StaticStrings::kFoo), nullptr);
242  EXPECT_EQ(*obj.get_ptr(StaticStrings::kFoo), 789);
243 
244  EXPECT_NE(obj.get_ptr(std::string{"a"}), nullptr);
245  EXPECT_EQ(*obj.get_ptr(std::string{"a"}), 123);
246  EXPECT_NE(obj.get_ptr(str), nullptr);
247  EXPECT_EQ(*obj.get_ptr(str), 123);
248 
249  EXPECT_EQ(obj.get_ptr(b), nullptr);
250  EXPECT_EQ(obj.get_ptr(StringPiece{b}), nullptr);
251  EXPECT_EQ(obj.get_ptr(StaticStrings::kBar), nullptr);
252 
253  // find()
254  EXPECT_EQ(obj.find(empty)->second, 456);
255  EXPECT_EQ(obj.find(nullptr)->second, 456);
256  EXPECT_EQ(obj.find(foo)->second, 789);
257 
258  EXPECT_EQ(obj.find(a)->second, 123);
259  EXPECT_EQ(obj.find(StaticStrings::kA)->second, 123);
260  EXPECT_EQ(obj.find("a")->second, 123);
261 
262  EXPECT_EQ(obj.find(sp)->second, 123);
263  EXPECT_EQ(obj.find(StringPiece{"a"})->second, 123);
264  EXPECT_EQ(obj.find(StaticStrings::kFoo)->second, 789);
265 
266  EXPECT_EQ(obj.find(std::string{"a"})->second, 123);
267  EXPECT_EQ(obj.find(str)->second, 123);
268 
269  EXPECT_TRUE(obj.find(b) == obj.items().end());
270  EXPECT_TRUE(obj.find(StringPiece{b}) == obj.items().end());
271  EXPECT_TRUE(obj.find(StaticStrings::kBar) == obj.items().end());
272 
273  // count()
274  EXPECT_EQ(obj.count(empty), 1);
275  EXPECT_EQ(obj.count(nullptr), 1);
276  EXPECT_EQ(obj.count(foo), 1);
277 
278  EXPECT_EQ(obj.count(a), 1);
279  EXPECT_EQ(obj.count(StaticStrings::kA), 1);
280  EXPECT_EQ(obj.count("a"), 1);
281 
282  EXPECT_EQ(obj.count(sp), 1);
283  EXPECT_EQ(obj.count(StringPiece{"a"}), 1);
284  EXPECT_EQ(obj.count(StaticStrings::kFoo), 1);
285 
286  EXPECT_EQ(obj.count(std::string{"a"}), 1);
287  EXPECT_EQ(obj.count(str), 1);
288 
289  EXPECT_EQ(obj.count(b), 0);
290  EXPECT_EQ(obj.count(StringPiece{b}), 0);
291  EXPECT_EQ(obj.count(StaticStrings::kBar), 0);
292 
293  // operator[]
294  EXPECT_EQ(obj[empty], 456);
295  EXPECT_EQ(obj[nullptr], 456);
296  EXPECT_EQ(obj[foo], 789);
297 
298  EXPECT_EQ(obj[a], 123);
299  EXPECT_EQ(obj[StaticStrings::kA], 123);
300  EXPECT_EQ(obj["a"], 123);
301 
302  EXPECT_EQ(obj[sp], 123);
303  EXPECT_EQ(obj[StringPiece{"a"}], 123);
304  EXPECT_EQ(obj[StaticStrings::kFoo], 789);
305 
306  EXPECT_EQ(obj[std::string{"a"}], 123);
307  EXPECT_EQ(obj[str], 123);
308 
309  EXPECT_EQ(obj[b], nullptr);
310  obj[b] = 42;
311  EXPECT_EQ(obj[StringPiece{b}], 42);
312  obj[StaticStrings::kBar] = 43;
313  EXPECT_EQ(obj["bar"], 43);
314 
315  // erase() + dynamic&&
316  EXPECT_EQ(obj.erase(StaticStrings::kB), /* num elements erased */ 1);
317 
318  dynamic obj2 = obj;
319  dynamic obj3 = obj;
320  dynamic obj4 = obj;
321  EXPECT_EQ(std::move(obj).find(StaticStrings::kFoo)->second, 789);
322  EXPECT_EQ(std::move(obj2).at(StaticStrings::kA), 123);
323  EXPECT_EQ(std::move(obj3)[nullptr], 456);
324  EXPECT_EQ(std::move(obj4).erase(StaticStrings::kBar), 1);
325 }
326 
327 TEST(Dynamic, CastFromVectorOfBooleans) {
328  std::vector<bool> b;
329  b.push_back(true);
330  b.push_back(false);
331  dynamic obj = dynamic::object("a", b[0])("b", b[1]);
332  EXPECT_EQ(obj.at("a"), true);
333  EXPECT_EQ(obj.at("b"), false);
334 }
335 
336 TEST(Dynamic, CastFromConstVectorOfBooleans) {
337  const std::vector<bool> b = {true, false};
338  dynamic obj = dynamic::object("a", b[0])("b", b[1]);
339  EXPECT_EQ(obj.at("a"), true);
340  EXPECT_EQ(obj.at("b"), false);
341 }
342 
343 TEST(Dynamic, ObjectErase) {
344  dynamic obj = dynamic::object("key1", "val")("key2", "val2");
345  EXPECT_EQ(obj.count("key1"), 1);
346  EXPECT_EQ(obj.count("key2"), 1);
347  EXPECT_EQ(obj.erase("key1"), 1);
348  EXPECT_EQ(obj.count("key1"), 0);
349  EXPECT_EQ(obj.count("key2"), 1);
350  EXPECT_EQ(obj.erase("key1"), 0);
351  obj["key1"] = 12;
352  EXPECT_EQ(obj.count("key1"), 1);
353  EXPECT_EQ(obj.count("key2"), 1);
354  auto it = obj.find("key2");
355  obj.erase(it);
356  EXPECT_EQ(obj.count("key1"), 1);
357  EXPECT_EQ(obj.count("key2"), 0);
358 
359  obj["asd"] = 42.0;
360  obj["foo"] = 42.0;
361  EXPECT_EQ(obj.size(), 3);
362  auto ret = obj.erase(std::next(obj.items().begin()), obj.items().end());
363  EXPECT_TRUE(ret == obj.items().end());
364  EXPECT_EQ(obj.size(), 1);
365  obj.erase(obj.items().begin());
366  EXPECT_TRUE(obj.empty());
367 }
368 
369 TEST(Dynamic, ArrayErase) {
370  dynamic arr = dynamic::array(1, 2, 3, 4, 5, 6);
371 
372  EXPECT_THROW(arr.erase(1), std::exception);
373  EXPECT_EQ(arr.size(), 6);
374  EXPECT_EQ(arr[0], 1);
375  arr.erase(arr.begin());
376  EXPECT_EQ(arr.size(), 5);
377 
378  arr.erase(std::next(arr.begin()), std::prev(arr.end()));
379  EXPECT_EQ(arr.size(), 2);
380  EXPECT_EQ(arr[0], 2);
381  EXPECT_EQ(arr[1], 6);
382 }
383 
384 TEST(Dynamic, StringBasics) {
385  dynamic str = "hello world";
386  EXPECT_EQ(11, str.size());
387  EXPECT_FALSE(str.empty());
388  str = "";
389  EXPECT_TRUE(str.empty());
390 }
391 
392 TEST(Dynamic, ArrayBasics) {
393  dynamic array = dynamic::array(1, 2, 3);
394  EXPECT_EQ(array.size(), 3);
395  EXPECT_EQ(array.at(0), 1);
396  EXPECT_EQ(array.at(1), 2);
397  EXPECT_EQ(array.at(2), 3);
398 
399  EXPECT_ANY_THROW(array.at(-1));
400  EXPECT_ANY_THROW(array.at(3));
401 
402  array.push_back("foo");
403  EXPECT_EQ(array.size(), 4);
404 
405  array.resize(12, "something");
406  EXPECT_EQ(array.size(), 12);
407  EXPECT_EQ(array[11], "something");
408 }
409 
410 TEST(Dynamic, DeepCopy) {
411  dynamic val = dynamic::array("foo", "bar", dynamic::array("foo1", "bar1"));
412  EXPECT_EQ(val.at(2).at(0), "foo1");
413  EXPECT_EQ(val.at(2).at(1), "bar1");
414  dynamic val2 = val;
415  EXPECT_EQ(val2.at(2).at(0), "foo1");
416  EXPECT_EQ(val2.at(2).at(1), "bar1");
417  EXPECT_EQ(val.at(2).at(0), "foo1");
418  EXPECT_EQ(val.at(2).at(1), "bar1");
419  val2.at(2).at(0) = "foo3";
420  val2.at(2).at(1) = "bar3";
421  EXPECT_EQ(val.at(2).at(0), "foo1");
422  EXPECT_EQ(val.at(2).at(1), "bar1");
423  EXPECT_EQ(val2.at(2).at(0), "foo3");
424  EXPECT_EQ(val2.at(2).at(1), "bar3");
425 
426  dynamic obj = dynamic::object("a", "b")("c", dynamic::array("d", "e", "f"));
427  EXPECT_EQ(obj.at("a"), "b");
428  dynamic obj2 = obj;
429  obj2.at("a") = dynamic::array(1, 2, 3);
430  EXPECT_EQ(obj.at("a"), "b");
431  dynamic expected = dynamic::array(1, 2, 3);
432  EXPECT_EQ(obj2.at("a"), expected);
433 }
434 
435 TEST(Dynamic, ArrayReassignment) {
436  dynamic o = 1;
437  dynamic d1 = dynamic::array(o);
438  EXPECT_EQ(dynamic::ARRAY, d1.type());
439 
440  d1 = dynamic::array(o);
441  EXPECT_EQ(dynamic::ARRAY, d1.type());
442 }
443 
444 TEST(Dynamic, Operator) {
445  bool caught = false;
446  try {
449  auto foo = d1 < d2;
450  LOG(ERROR) << "operator < returned " << static_cast<int>(foo)
451  << " instead of throwing";
452  } catch (std::exception const&) {
453  caught = true;
454  }
455  EXPECT_TRUE(caught);
456 
457  dynamic foo = "asd";
458  dynamic bar = "bar";
459  dynamic sum = foo + bar;
460  EXPECT_EQ(sum, "asdbar");
461 
462  dynamic some = 12;
463  dynamic nums = 4;
464  dynamic math = some / nums;
465  EXPECT_EQ(math, 3);
466 }
467 
468 TEST(Dynamic, Conversions) {
469  dynamic str = "12.0";
470  EXPECT_EQ(str.asDouble(), 12.0);
471  EXPECT_ANY_THROW(str.asInt());
472  EXPECT_ANY_THROW(str.asBool());
473 
474  str = "12";
475  EXPECT_EQ(str.asInt(), 12);
476  EXPECT_EQ(str.asDouble(), 12.0);
477  str = "0";
478  EXPECT_EQ(str.asBool(), false);
479  EXPECT_EQ(str.asInt(), 0);
480  EXPECT_EQ(str.asDouble(), 0);
481  EXPECT_EQ(str.asString(), "0");
482 
483  dynamic num = 12;
484  EXPECT_EQ("12", num.asString());
485  EXPECT_EQ(12.0, num.asDouble());
486 }
487 
488 TEST(Dynamic, GetSetDefaultTest) {
489  dynamic d1 = dynamic::object("foo", "bar");
490  EXPECT_EQ(d1.getDefault("foo", "baz"), "bar");
491  EXPECT_EQ(d1.getDefault("quux", "baz"), "baz");
492 
493  dynamic d2 = dynamic::object("foo", "bar");
494  EXPECT_EQ(d2.setDefault("foo", "quux"), "bar");
495  d2.setDefault("bar", dynamic::array).push_back(42);
496  EXPECT_EQ(d2["bar"][0], 42);
497 
499  EXPECT_EQ(d3.getDefault("foo"), empty);
500  d3.setDefault("foo")["bar"] = "baz";
501  EXPECT_EQ(d3["foo"]["bar"], "baz");
502 
503  // we do not allow getDefault/setDefault on arrays
504  dynamic d4 = dynamic::array;
505  EXPECT_ANY_THROW(d4.getDefault("foo", "bar"));
506  EXPECT_ANY_THROW(d4.setDefault("foo", "bar"));
507 
508  // Using dynamic keys
509  dynamic k10{10}, k20{20}, kTrue{true};
510  dynamic d5 = dynamic::object(k10, "foo");
511  EXPECT_EQ(d5.setDefault(k10, "bar"), "foo");
512  EXPECT_EQ(d5.setDefault(k20, "bar"), "bar");
513  EXPECT_EQ(d5.setDefault(kTrue, "baz"), "baz");
514  EXPECT_EQ(d5.setDefault(StaticStrings::kA, "foo"), "foo");
515  EXPECT_EQ(d5.setDefault(StaticStrings::kB, "foo"), "foo");
516  EXPECT_EQ(d5.setDefault(StaticStrings::kFoo, "bar"), "bar");
517  EXPECT_EQ(d5.setDefault(StaticStrings::kBar, "foo"), "foo");
518 }
519 
520 TEST(Dynamic, ObjectForwarding) {
521  // Make sure dynamic::object can be constructed the same way as any
522  // dynamic.
523  dynamic d = dynamic::object("asd", dynamic::array("foo", "bar"));
524  // clang-format off
525  dynamic d2 = dynamic::object("key2", dynamic::array("value", "words"))
526  ("key", "value1");
527  // clang-format on
528 }
529 
530 TEST(Dynamic, GetPtr) {
531  dynamic array = dynamic::array(1, 2, "three");
532  EXPECT_TRUE(array.get_ptr(0));
533  EXPECT_FALSE(array.get_ptr(-1));
534  EXPECT_FALSE(array.get_ptr(3));
535  EXPECT_EQ(dynamic("three"), *array.get_ptr(2));
536  const dynamic& carray = array;
537  EXPECT_EQ(dynamic("three"), *carray.get_ptr(2));
538 
539  dynamic object = dynamic::object("one", 1)("two", 2);
540  EXPECT_TRUE(object.get_ptr("one"));
541  EXPECT_FALSE(object.get_ptr("three"));
542  EXPECT_EQ(dynamic(2), *object.get_ptr("two"));
543  *object.get_ptr("one") = 11;
544  EXPECT_EQ(dynamic(11), *object.get_ptr("one"));
545  const dynamic& cobject = object;
546  EXPECT_EQ(dynamic(2), *cobject.get_ptr("two"));
547 }
548 
549 TEST(Dynamic, Assignment) {
550  const dynamic ds[] = {
551  dynamic::array(1, 2, 3),
552  dynamic::object("a", true),
553  24,
554  26.5,
555  true,
556  "hello",
557  };
558  const dynamic dd[] = {
559  dynamic::array(5, 6),
560  dynamic::object("t", "T")(1, 7),
561  9000,
562  3.14159,
563  false,
564  "world",
565  };
566  for (const auto& source : ds) {
567  for (const auto& dest : dd) {
568  dynamic tmp(dest);
569  EXPECT_EQ(tmp, dest);
570  tmp = source;
571  EXPECT_EQ(tmp, source);
572  }
573  }
574 }
575 
577  return std::string(100, 'a');
578 }
579 
580 TEST(Dynamic, GetDefault) {
581  const auto s = make_long_string();
582  dynamic kDynamicKey{10};
583  dynamic ds(s);
584  dynamic tmp(s);
585  dynamic d1 = dynamic::object("key1", s);
586  dynamic d2 = dynamic::object("key2", s);
587  dynamic d3 = dynamic::object("key3", s);
588  dynamic d4 = dynamic::object("key4", s);
589  // lvalue - lvalue
590  dynamic ayy("ayy");
591  EXPECT_EQ(ds, d1.getDefault("key1", ayy));
592  EXPECT_EQ(ds, d1.getDefault("key1", ayy));
593  EXPECT_EQ(ds, d1.getDefault("not-a-key", tmp));
594  EXPECT_EQ(ds, d1.getDefault(StaticStrings::kA, tmp));
595  EXPECT_EQ(ds, d1.getDefault(StaticStrings::kB, tmp));
596  EXPECT_EQ(ds, d1.getDefault(StaticStrings::kFoo, tmp));
597  EXPECT_EQ(ds, d1.getDefault(StaticStrings::kBar, tmp));
598  EXPECT_EQ(ds, d1.getDefault(kDynamicKey, tmp));
599  EXPECT_EQ(ds, tmp);
600  // lvalue - rvalue
601  EXPECT_EQ(ds, d1.getDefault("key1", "ayy"));
602  EXPECT_EQ(ds, d1.getDefault("key1", "ayy"));
603  EXPECT_EQ(ds, d1.getDefault("not-a-key", std::move(tmp)));
604  EXPECT_NE(ds, tmp);
605  tmp = s;
606  EXPECT_EQ(ds, d1.getDefault(StaticStrings::kA, std::move(tmp)));
607  EXPECT_NE(ds, tmp);
608  tmp = s;
609  EXPECT_EQ(ds, d1.getDefault(StaticStrings::kB, std::move(tmp)));
610  EXPECT_NE(ds, tmp);
611  tmp = s;
612  EXPECT_EQ(ds, d1.getDefault(StaticStrings::kFoo, std::move(tmp)));
613  EXPECT_NE(ds, tmp);
614  tmp = s;
615  EXPECT_EQ(ds, d1.getDefault(StaticStrings::kBar, std::move(tmp)));
616  EXPECT_NE(ds, tmp);
617  tmp = s;
618  EXPECT_EQ(ds, d1.getDefault(kDynamicKey, std::move(tmp)));
619  EXPECT_NE(ds, tmp);
620  // rvalue - lvalue
621  tmp = s;
622  EXPECT_EQ(ds, std::move(d1).getDefault("key1", ayy));
623  EXPECT_NE(ds, d1["key1"]);
624  EXPECT_EQ(ds, std::move(d2).getDefault("not-a-key", tmp));
625  EXPECT_EQ(dynamic(dynamic::object("key2", s)), d2);
626  EXPECT_EQ(ds, tmp);
627  EXPECT_EQ(ds, std::move(d2).getDefault(StaticStrings::kA, tmp));
628  EXPECT_EQ(dynamic(dynamic::object("key2", s)), d2);
629  EXPECT_EQ(ds, tmp);
630  EXPECT_EQ(ds, std::move(d2).getDefault(StaticStrings::kB, tmp));
631  EXPECT_EQ(dynamic(dynamic::object("key2", s)), d2);
632  EXPECT_EQ(ds, tmp);
633  EXPECT_EQ(ds, std::move(d2).getDefault(StaticStrings::kFoo, tmp));
634  EXPECT_EQ(dynamic(dynamic::object("key2", s)), d2);
635  EXPECT_EQ(ds, tmp);
636  EXPECT_EQ(ds, std::move(d2).getDefault(StaticStrings::kBar, tmp));
637  EXPECT_EQ(dynamic(dynamic::object("key2", s)), d2);
638  EXPECT_EQ(ds, tmp);
639  EXPECT_EQ(ds, std::move(d2).getDefault(kDynamicKey, tmp));
640  EXPECT_EQ(dynamic(dynamic::object("key2", s)), d2);
641  EXPECT_EQ(ds, tmp);
642  // rvalue - rvalue
643  EXPECT_EQ(ds, std::move(d3).getDefault("key3", std::move(tmp)));
644  EXPECT_NE(ds, d3["key3"]);
645  EXPECT_EQ(ds, tmp);
646  EXPECT_EQ(ds, std::move(d4).getDefault("not-a-key", std::move(tmp)));
647  EXPECT_EQ(dynamic(dynamic::object("key4", s)), d4);
648  EXPECT_NE(ds, tmp);
649  tmp = s;
650  EXPECT_EQ(ds, std::move(d4).getDefault(StaticStrings::kA, std::move(tmp)));
651  EXPECT_EQ(dynamic(dynamic::object("key4", s)), d4);
652  EXPECT_NE(ds, tmp);
653  tmp = s;
654  EXPECT_EQ(ds, std::move(d4).getDefault(StaticStrings::kB, std::move(tmp)));
655  EXPECT_EQ(dynamic(dynamic::object("key4", s)), d4);
656  EXPECT_NE(ds, tmp);
657  tmp = s;
658  EXPECT_EQ(ds, std::move(d4).getDefault(StaticStrings::kFoo, std::move(tmp)));
659  EXPECT_EQ(dynamic(dynamic::object("key4", s)), d4);
660  EXPECT_NE(ds, tmp);
661  tmp = s;
662  EXPECT_EQ(ds, std::move(d4).getDefault(StaticStrings::kBar, std::move(tmp)));
663  EXPECT_EQ(dynamic(dynamic::object("key4", s)), d4);
664  EXPECT_NE(ds, tmp);
665  tmp = s;
666  EXPECT_EQ(ds, std::move(d4).getDefault(kDynamicKey, std::move(tmp)));
667  EXPECT_EQ(dynamic(dynamic::object("key4", s)), d4);
668  EXPECT_NE(ds, tmp);
669 }
670 
671 TEST(Dynamic, GetString) {
672  const dynamic c(make_long_string());
675 
676  auto s = make_long_string();
677 
678  EXPECT_EQ(s, c.getString());
679  EXPECT_EQ(s, c.getString());
680 
681  d.getString() += " hello";
682  EXPECT_EQ(s + " hello", d.getString());
683  EXPECT_EQ(s + " hello", d.getString());
684 
685  EXPECT_EQ(s, std::move(m).getString());
686  EXPECT_EQ(s, m.getString());
687  auto moved = std::move(m).getString();
688  EXPECT_EQ(s, moved);
689  EXPECT_NE(dynamic(s), m);
690 }
691 
692 TEST(Dynamic, GetSmallThings) {
693  const dynamic cint(5);
694  const dynamic cdouble(5.0);
695  const dynamic cbool(true);
696  dynamic dint(5);
697  dynamic ddouble(5.0);
698  dynamic dbool(true);
699  dynamic mint(5);
700  dynamic mdouble(5.0);
701  dynamic mbool(true);
702 
703  EXPECT_EQ(5, cint.getInt());
704  dint.getInt() = 6;
705  EXPECT_EQ(6, dint.getInt());
706  EXPECT_EQ(5, std::move(mint).getInt());
707 
708  EXPECT_EQ(5.0, cdouble.getDouble());
709  ddouble.getDouble() = 6.0;
710  EXPECT_EQ(6.0, ddouble.getDouble());
711  EXPECT_EQ(5.0, std::move(mdouble).getDouble());
712 
713  EXPECT_TRUE(cbool.getBool());
714  dbool.getBool() = false;
715  EXPECT_FALSE(dbool.getBool());
716  EXPECT_TRUE(std::move(mbool).getBool());
717 }
718 
719 TEST(Dynamic, At) {
720  const dynamic cd = dynamic::object("key1", make_long_string());
721  dynamic dd = dynamic::object("key1", make_long_string());
722  dynamic md = dynamic::object("key1", make_long_string());
723 
725  EXPECT_EQ(ds, cd.at("key1"));
726  EXPECT_EQ(ds, cd.at("key1"));
727 
728  dd.at("key1").getString() += " hello";
729  EXPECT_EQ(dynamic(make_long_string() + " hello"), dd.at("key1"));
730  EXPECT_EQ(dynamic(make_long_string() + " hello"), dd.at("key1"));
731 
732  EXPECT_EQ(ds, std::move(md).at("key1")); // move available, but not performed
733  EXPECT_EQ(ds, md.at("key1"));
734  dynamic moved = std::move(md).at("key1"); // move performed
735  EXPECT_EQ(ds, moved);
736  EXPECT_NE(ds, md.at("key1"));
737 }
738 
739 TEST(Dynamic, Brackets) {
740  const dynamic cd = dynamic::object("key1", make_long_string());
741  dynamic dd = dynamic::object("key1", make_long_string());
742  dynamic md = dynamic::object("key1", make_long_string());
743 
745  EXPECT_EQ(ds, cd["key1"]);
746  EXPECT_EQ(ds, cd["key1"]);
747 
748  dd["key1"].getString() += " hello";
749  EXPECT_EQ(dynamic(make_long_string() + " hello"), dd["key1"]);
750  EXPECT_EQ(dynamic(make_long_string() + " hello"), dd["key1"]);
751 
752  EXPECT_EQ(ds, std::move(md)["key1"]); // move available, but not performed
753  EXPECT_EQ(ds, md["key1"]);
754  dynamic moved = std::move(md)["key1"]; // move performed
755  EXPECT_EQ(ds, moved);
756  EXPECT_NE(ds, md["key1"]);
757 }
758 
759 TEST(Dynamic, PrintNull) {
760  std::stringstream ss;
761  ss << folly::dynamic(nullptr);
762  EXPECT_EQ("null", ss.str());
763 }
764 
765 TEST(Dynamic, WriteThroughArrayIterators) {
766  dynamic const cint(0);
767  dynamic d = dynamic::array(cint, cint, cint);
768  size_t size = d.size();
769 
770  for (auto& val : d) {
771  EXPECT_EQ(val, cint);
772  }
773  EXPECT_EQ(d.size(), size);
774 
776  for (auto& val : d) {
777  val = ds; // assign through reference
778  }
779 
780  ds = "short string";
781  dynamic ds2(make_long_string());
782 
783  for (auto& val : d) {
784  EXPECT_EQ(val, ds2);
785  }
786  EXPECT_EQ(d.size(), size);
787 }
788 
789 TEST(Dynamic, MoveOutOfArrayIterators) {
791  dynamic d = dynamic::array(ds, ds, ds);
792  size_t size = d.size();
793 
794  for (auto& val : d) {
795  EXPECT_EQ(val, ds);
796  }
797  EXPECT_EQ(d.size(), size);
798 
799  for (auto& val : d) {
800  dynamic waste = std::move(val); // force moving out
801  EXPECT_EQ(waste, ds);
802  }
803 
804  for (auto& val : d) {
805  EXPECT_NE(val, ds);
806  }
807  EXPECT_EQ(d.size(), size);
808 }
809 
810 TEST(Dynamic, WriteThroughObjectIterators) {
811  dynamic const cint(0);
812  dynamic d = dynamic::object("key1", cint)("key2", cint);
813  size_t size = d.size();
814 
815  for (auto& val : d.items()) {
816  EXPECT_EQ(val.second, cint);
817  }
818  EXPECT_EQ(d.size(), size);
819 
821  for (auto& val : d.items()) {
822  val.second = ds; // assign through reference
823  }
824 
825  ds = "short string";
826  dynamic ds2(make_long_string());
827  for (auto& val : d.items()) {
828  EXPECT_EQ(val.second, ds2);
829  }
830  EXPECT_EQ(d.size(), size);
831 }
832 
833 TEST(Dynamic, MoveOutOfObjectIterators) {
835  dynamic d = dynamic::object("key1", ds)("key2", ds);
836  size_t size = d.size();
837 
838  for (auto& val : d.items()) {
839  EXPECT_EQ(val.second, ds);
840  }
841  EXPECT_EQ(d.size(), size);
842 
843  for (auto& val : d.items()) {
844  dynamic waste = std::move(val.second); // force moving out
845  EXPECT_EQ(waste, ds);
846  }
847 
848  for (auto& val : d.items()) {
849  EXPECT_NE(val.second, ds);
850  }
851  EXPECT_EQ(d.size(), size);
852 }
853 
854 TEST(Dynamic, ArrayIteratorInterop) {
855  dynamic d = dynamic::array(0, 1, 2);
856  dynamic const& cdref = d;
857 
858  auto it = d.begin();
859  auto cit = cdref.begin();
860 
861  EXPECT_EQ(it, cit);
862  EXPECT_EQ(cit, d.begin());
863  EXPECT_EQ(it, cdref.begin());
864 
865  // Erase using non-const iterator
866  it = d.erase(it);
867  cit = cdref.begin();
868  EXPECT_EQ(*it, 1);
869  EXPECT_EQ(cit, it);
870 
871  // Assign from non-const to const, preserve equality
872  decltype(cit) cit2 = it;
873  EXPECT_EQ(cit, cit2);
874 }
875 
876 TEST(Dynamic, ObjectIteratorInterop) {
877  dynamic ds = make_long_string();
878  dynamic d = dynamic::object(0, ds)(1, ds)(2, ds);
879  dynamic const& cdref = d;
880 
881  auto it = d.find(0);
882  auto cit = cdref.find(0);
883  EXPECT_NE(it, cdref.items().end());
884  EXPECT_NE(cit, cdref.items().end());
885  EXPECT_EQ(it, cit);
886 
887  ++cit;
888  // Erase using non-const iterator
889  auto it2 = d.erase(it);
890  EXPECT_EQ(cit, it2);
891 
892  // Assign from non-const to const, preserve equality
893  decltype(cit) cit2 = it2;
894  EXPECT_EQ(cit, cit2);
895 }
896 
897 TEST(Dynamic, MergePatchWithNonObject) {
898  dynamic target = dynamic::object("a", "b")("c", "d");
899 
900  dynamic patch = dynamic::array(1, 2, 3);
901  target.merge_patch(patch);
902 
903  EXPECT_TRUE(target.isArray());
904 }
905 
906 TEST(Dynamic, MergePatchReplaceInFlatObject) {
907  dynamic target = dynamic::object("a", "b")("c", "d");
908  dynamic patch = dynamic::object("a", "z");
909 
910  target.merge_patch(patch);
911 
912  EXPECT_EQ("z", target["a"].getString());
913  EXPECT_EQ("d", target["c"].getString());
914 }
915 
916 TEST(Dynamic, MergePatchAddInFlatObject) {
917  dynamic target = dynamic::object("a", "b")("c", "d");
918  dynamic patch = dynamic::object("e", "f");
919  target.merge_patch(patch);
920 
921  EXPECT_EQ("b", target["a"].getString());
922  EXPECT_EQ("d", target["c"].getString());
923  EXPECT_EQ("f", target["e"].getString());
924 }
925 
926 TEST(Dynamic, MergePatchReplaceInNestedObject) {
927  dynamic target = dynamic::object("a", dynamic::object("d", 10))("b", "c");
928  dynamic patch = dynamic::object("a", dynamic::object("d", 100));
929  target.merge_patch(patch);
930 
931  EXPECT_EQ(100, target["a"]["d"].getInt());
932  EXPECT_EQ("c", target["b"].getString());
933 }
934 
935 TEST(Dynamic, MergePatchAddInNestedObject) {
936  dynamic target = dynamic::object("a", dynamic::object("d", 10))("b", "c");
937  dynamic patch = dynamic::object("a", dynamic::object("e", "f"));
938 
939  target.merge_patch(patch);
940 
941  EXPECT_EQ(10, target["a"]["d"].getInt());
942  EXPECT_EQ("f", target["a"]["e"].getString());
943  EXPECT_EQ("c", target["b"].getString());
944 }
945 
946 TEST(Dynamic, MergeNestePatch) {
947  dynamic target = dynamic::object("a", dynamic::object("d", 10))("b", "c");
948  dynamic patch = dynamic::object(
949  "a", dynamic::object("d", dynamic::array(1, 2, 3)))("b", 100);
950  target.merge_patch(patch);
951 
952  EXPECT_EQ(100, target["b"].getInt());
953  {
954  auto ary = patch["a"]["d"];
955  ASSERT_TRUE(ary.isArray());
956  EXPECT_EQ(1, ary[0].getInt());
957  EXPECT_EQ(2, ary[1].getInt());
958  EXPECT_EQ(3, ary[2].getInt());
959  }
960 }
961 
962 TEST(Dynamic, MergePatchRemoveInFlatObject) {
963  dynamic target = dynamic::object("a", "b")("c", "d");
964  dynamic patch = dynamic::object("c", nullptr);
965  target.merge_patch(patch);
966 
967  EXPECT_EQ("b", target["a"].getString());
968  EXPECT_EQ(0, target.count("c"));
969 }
970 
971 TEST(Dynamic, MergePatchRemoveInNestedObject) {
972  dynamic target =
973  dynamic::object("a", dynamic::object("d", 10)("e", "f"))("b", "c");
974  dynamic patch = dynamic::object("a", dynamic::object("e", nullptr));
975  target.merge_patch(patch);
976 
977  EXPECT_EQ(10, target["a"]["d"].getInt());
978  EXPECT_EQ(0, target["a"].count("e"));
979  EXPECT_EQ("c", target["b"].getString());
980 }
981 
982 TEST(Dynamic, MergePatchRemoveNonExistent) {
983  dynamic target = dynamic::object("a", "b")("c", "d");
984  dynamic patch = dynamic::object("e", nullptr);
985  target.merge_patch(patch);
986 
987  EXPECT_EQ("b", target["a"].getString());
988  EXPECT_EQ("d", target["c"].getString());
989  EXPECT_EQ(2, target.size());
990 }
991 
992 TEST(Dynamic, MergeDiffFlatObjects) {
993  dynamic source = dynamic::object("a", 0)("b", 1)("c", 2);
994  dynamic target = dynamic::object("a", 1)("b", 2);
995  auto patch = dynamic::merge_diff(source, target);
996 
997  EXPECT_EQ(3, patch.size());
998  EXPECT_EQ(1, patch["a"].getInt());
999  EXPECT_EQ(2, patch["b"].getInt());
1000  EXPECT_TRUE(patch["c"].isNull());
1001 
1002  source.merge_patch(patch);
1003  EXPECT_EQ(source, target);
1004 }
1005 
1006 TEST(Dynamic, MergeDiffNestedObjects) {
1007  dynamic source = dynamic::object("a", dynamic::object("b", 1)("c", 2))(
1008  "d", dynamic::array(1, 2, 3));
1009  dynamic target = dynamic::object("a", dynamic::object("b", 2))(
1010  "d", dynamic::array(2, 3, 4));
1011 
1012  auto patch = dynamic::merge_diff(source, target);
1013 
1014  EXPECT_EQ(2, patch.size());
1015  EXPECT_EQ(2, patch["a"].size());
1016 
1017  EXPECT_EQ(2, patch["a"]["b"].getInt());
1018  EXPECT_TRUE(patch["a"]["c"].isNull());
1019 
1020  EXPECT_TRUE(patch["d"].isArray());
1021  EXPECT_EQ(3, patch["d"].size());
1022  EXPECT_EQ(2, patch["d"][0].getInt());
1023  EXPECT_EQ(3, patch["d"][1].getInt());
1024  EXPECT_EQ(4, patch["d"][2].getInt());
1025 
1026  source.merge_patch(patch);
1027  EXPECT_EQ(source, target);
1028 }
1029 
1030 using folly::json_pointer;
1031 
1032 TEST(Dynamic, JSONPointer) {
1033  dynamic target = dynamic::object;
1034  dynamic ary = dynamic::array("bar", "baz", dynamic::array("bletch", "xyzzy"));
1035  target["foo"] = ary;
1036  target[""] = 0;
1037  target["a/b"] = 1;
1038  target["c%d"] = 2;
1039  target["e^f"] = 3;
1040  target["g|h"] = 4;
1041  target["i\\j"] = 5;
1042  target["k\"l"] = 6;
1043  target[" "] = 7;
1044  target["m~n"] = 8;
1045  target["xyz"] = dynamic::object;
1046  target["xyz"][""] = dynamic::object("nested", "abc");
1047  target["xyz"]["def"] = dynamic::array(1, 2, 3);
1048  target["long_array"] = dynamic::array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
1049  target["-"] = dynamic::object("x", "y");
1050 
1051  EXPECT_EQ(target, *target.get_ptr(json_pointer::parse("")));
1052  EXPECT_EQ(ary, *(target.get_ptr(json_pointer::parse("/foo"))));
1053  EXPECT_EQ("bar", target.get_ptr(json_pointer::parse("/foo/0"))->getString());
1054  EXPECT_EQ(0, target.get_ptr(json_pointer::parse("/"))->getInt());
1055  EXPECT_EQ(1, target.get_ptr(json_pointer::parse("/a~1b"))->getInt());
1056  EXPECT_EQ(2, target.get_ptr(json_pointer::parse("/c%d"))->getInt());
1057  EXPECT_EQ(3, target.get_ptr(json_pointer::parse("/e^f"))->getInt());
1058  EXPECT_EQ(4, target.get_ptr(json_pointer::parse("/g|h"))->getInt());
1059  EXPECT_EQ(5, target.get_ptr(json_pointer::parse("/i\\j"))->getInt());
1060  EXPECT_EQ(6, target.get_ptr(json_pointer::parse("/k\"l"))->getInt());
1061  EXPECT_EQ(7, target.get_ptr(json_pointer::parse("/ "))->getInt());
1062  EXPECT_EQ(8, target.get_ptr(json_pointer::parse("/m~0n"))->getInt());
1063  // empty key in path
1064  EXPECT_EQ(
1065  "abc", target.get_ptr(json_pointer::parse("/xyz//nested"))->getString());
1066  EXPECT_EQ(3, target.get_ptr(json_pointer::parse("/xyz/def/2"))->getInt());
1067  EXPECT_EQ("baz", ary.get_ptr(json_pointer::parse("/1"))->getString());
1068  EXPECT_EQ("bletch", ary.get_ptr(json_pointer::parse("/2/0"))->getString());
1069  // double-digit index
1070  EXPECT_EQ(
1071  12, target.get_ptr(json_pointer::parse("/long_array/11"))->getInt());
1072  // allow '-' to index in objects
1073  EXPECT_EQ("y", target.get_ptr(json_pointer::parse("/-/x"))->getString());
1074 
1075  // invalid JSON pointers formatting when accessing array
1076  EXPECT_THROW(
1077  target.get_ptr(json_pointer::parse("/foo/01")), std::invalid_argument);
1078 
1079  // non-existent keys/indexes
1080  EXPECT_EQ(nullptr, ary.get_ptr(json_pointer::parse("/3")));
1081  EXPECT_EQ(nullptr, target.get_ptr(json_pointer::parse("/unknown_key")));
1082  // intermediate key not found
1083  EXPECT_EQ(nullptr, target.get_ptr(json_pointer::parse("/foox/test")));
1084  // Intermediate key is '-'
1085  EXPECT_EQ(nullptr, target.get_ptr(json_pointer::parse("/foo/-/key")));
1086 
1087  // invalid path in object (key in array)
1088  EXPECT_THROW(
1089  target.get_ptr(json_pointer::parse("/foo/1/bar")), folly::TypeError);
1090 
1091  // Allow "-" index in the array
1092  EXPECT_EQ(nullptr, target.get_ptr(json_pointer::parse("/foo/-")));
1093 }
size_t parse(const char *buf, size_t len)
Definition: test.c:1591
const Map::mapped_type * get_ptr(const Map &map, const Key &key)
Definition: MapUtil.h:169
#define EXPECT_ANY_THROW(statement)
Definition: gtest.h:1847
static ObjectMaker object()
Definition: dynamic-inl.h:240
void * object
Definition: AtFork.cpp:32
IfIsNonStringDynamicConvertible< K, dynamic > getDefault(K &&k, const dynamic &v=dynamic::object) const &
Definition: dynamic-inl.h:685
std::atomic< int64_t > sum(0)
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
char b
double getDouble() const &
Definition: dynamic-inl.h:534
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
double asDouble() const
Definition: dynamic-inl.h:521
dest
Definition: upload.py:394
double val
Definition: String.cpp:273
RfcParam d5(false, exampleHex3)
IfIsNonStringDynamicConvertible< K, std::size_t > count(K &&) const
Definition: dynamic-inl.h:843
const std::string & getString() const &
Definition: dynamic-inl.h:531
bool asBool() const
Definition: dynamic-inl.h:527
IfIsNonStringDynamicConvertible< K, dynamic & > setDefault(K &&k, V &&v)
Definition: dynamic-inl.h:731
bool isArray() const
Definition: dynamic-inl.h:498
int64_t getInt() const &
Definition: dynamic-inl.h:537
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
bool isNull() const
Definition: dynamic-inl.h:507
RfcParam d4(true, exampleHex2)
constexpr auto empty(C const &c) -> decltype(c.empty())
Definition: Access.h:55
bool empty() const
Definition: dynamic-inl.h:815
void insert(K &&, V &&val)
Definition: dynamic-inl.h:853
static map< string, int > m
int64_t asInt() const
Definition: dynamic-inl.h:524
IfIsNonStringDynamicConvertible< K, const_item_iterator > find(K &&) const
Definition: dynamic-inl.h:824
char a
void push_back(dynamic const &)
Definition: dynamic-inl.h:969
folly::Singleton< int > bar
IfIsNonStringDynamicConvertible< K, std::size_t > erase(K &&)
Definition: dynamic-inl.h:916
int * count
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
void update(const dynamic &mergeObj)
Definition: dynamic-inl.h:858
IterableProxy< const_item_iterator > items() const
Definition: dynamic-inl.h:476
const char * string
Definition: Conv.cpp:212
std::size_t size() const
Definition: dynamic.cpp:275
static void array(EmptyArrayTag)
Definition: dynamic-inl.h:233
TEST(Dynamic, Default)
Definition: DynamicTest.cpp:28
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
static set< string > s
bool getBool() const &
Definition: dynamic-inl.h:540
IfIsNonStringDynamicConvertible< K, dynamic const & > at(K &&) const &
Definition: dynamic-inl.h:792
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
Type type() const
Definition: dynamic-inl.h:514
RfcParam d3(false, exampleHex1)
Range< const char * > StringPiece
void update_missing(const dynamic &other)
Definition: dynamic-inl.h:868
const_iterator begin() const
Definition: dynamic-inl.h:432
char c
void merge_patch(const dynamic &patch)
Definition: dynamic-inl.h:881
void merge(unsigned int iters, size_t maxSize, size_t bufSize)
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
void resize(std::size_t n, dynamic const &=nullptr)
Definition: dynamic-inl.h:964
const_iterator end() const
Definition: dynamic-inl.h:435
const dynamic * get_ptr(json_pointer const &) const &
Definition: dynamic.cpp:371
constexpr detail::First first
Definition: Base-inl.h:2553
def next(obj)
Definition: ast.py:58
std::string make_long_string()