proxygen
JsonTestUtil.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018-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 
18 
19 #include <algorithm>
20 #include <cmath>
21 
22 #include <folly/Conv.h>
23 #include <folly/json.h>
24 #include <folly/lang/Assume.h>
25 
26 namespace folly {
27 
28 bool compareJson(StringPiece json1, StringPiece json2) {
29  auto obj1 = parseJson(json1);
30  auto obj2 = parseJson(json2);
31  return obj1 == obj2;
32 }
33 
34 namespace {
35 
36 bool isClose(double x, double y, double tolerance) {
37  return std::abs(x - y) <= tolerance;
38 }
39 
40 } // namespace
41 
43  const dynamic& obj1,
44  const dynamic& obj2,
45  double tolerance) {
46  if (obj1.type() != obj2.type()) {
47  if (obj1.isNumber() && obj2.isNumber()) {
48  const auto& integ = obj1.isInt() ? obj1 : obj2;
49  const auto& doubl = obj1.isInt() ? obj2 : obj1;
50  // Use to<double> to fail on precision loss for very large
51  // integers (in which case the comparison does not make sense).
52  return isClose(to<double>(integ.asInt()), doubl.asDouble(), tolerance);
53  }
54  return false;
55  }
56 
57  switch (obj1.type()) {
58  case dynamic::Type::NULLT:
59  return true;
60  case dynamic::Type::ARRAY:
61  if (obj1.size() != obj2.size()) {
62  return false;
63  }
64  for (auto i1 = obj1.begin(), i2 = obj2.begin(); i1 != obj1.end();
65  ++i1, ++i2) {
66  if (!compareDynamicWithTolerance(*i1, *i2, tolerance)) {
67  return false;
68  }
69  }
70  return true;
71  case dynamic::Type::BOOL:
72  return obj1.asBool() == obj2.asBool();
73  case dynamic::Type::DOUBLE:
74  return isClose(obj1.asDouble(), obj2.asDouble(), tolerance);
75  case dynamic::Type::INT64:
76  return obj1.asInt() == obj2.asInt();
77  case dynamic::Type::OBJECT:
78  if (obj1.size() != obj2.size()) {
79  return false;
80  }
81 
82  return std::all_of(
83  obj1.items().begin(), obj1.items().end(), [&](const auto& item) {
84  const auto& value1 = item.second;
85  const auto value2 = obj2.get_ptr(item.first);
86  return value2 &&
87  compareDynamicWithTolerance(value1, *value2, tolerance);
88  });
90  return obj1.asString() == obj2.asString();
91  }
92 
94 }
95 
97  StringPiece json1,
98  StringPiece json2,
99  double tolerance) {
100  auto obj1 = parseJson(json1);
101  auto obj2 = parseJson(json2);
102  return compareDynamicWithTolerance(obj1, obj2, tolerance);
103 }
104 
105 } // namespace folly
Definition: InvokeTest.cpp:58
dynamic parseJson(StringPiece range)
Definition: json.cpp:900
double asDouble() const
Definition: dynamic-inl.h:521
bool compareJsonWithTolerance(StringPiece json1, StringPiece json2, double tolerance)
bool asBool() const
Definition: dynamic-inl.h:527
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
#define STRING
bool isNumber() const
Definition: dynamic-inl.h:510
FOLLY_ALWAYS_INLINE void assume_unreachable()
Definition: Assume.h:59
std::string asString() const
Definition: dynamic-inl.h:518
int64_t asInt() const
Definition: dynamic-inl.h:524
IterableProxy< const_item_iterator > items() const
Definition: dynamic-inl.h:476
std::size_t size() const
Definition: dynamic.cpp:275
Definition: InvokeTest.cpp:65
bool isInt() const
Definition: dynamic-inl.h:504
Type type() const
Definition: dynamic-inl.h:514
const_iterator begin() const
Definition: dynamic-inl.h:432
bool compareJson(StringPiece json1, StringPiece json2)
bool compareDynamicWithTolerance(const dynamic &obj1, const dynamic &obj2, double tolerance)
const_iterator end() const
Definition: dynamic-inl.h:435
const dynamic * get_ptr(json_pointer const &) const &
Definition: dynamic.cpp:371