1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under the BSD-style license found in the
3 // LICENSE file in the root directory of this source tree. An additional grant
4 // of patent rights can be found in the PATENTS file in the same directory.
12 #include "rocksdb/utilities/json_document.h"
14 #include "util/testutil.h"
15 #include "util/testharness.h"
19 void AssertField(const JSONDocument
& json
, const std::string
& field
) {
20 ASSERT_TRUE(json
.Contains(field
));
21 ASSERT_TRUE(json
[field
].IsNull());
24 void AssertField(const JSONDocument
& json
, const std::string
& field
,
25 const std::string
& expected
) {
26 ASSERT_TRUE(json
.Contains(field
));
27 ASSERT_TRUE(json
[field
].IsString());
28 ASSERT_EQ(expected
, json
[field
].GetString());
31 void AssertField(const JSONDocument
& json
, const std::string
& field
,
33 ASSERT_TRUE(json
.Contains(field
));
34 ASSERT_TRUE(json
[field
].IsInt64());
35 ASSERT_EQ(expected
, json
[field
].GetInt64());
38 void AssertField(const JSONDocument
& json
, const std::string
& field
,
40 ASSERT_TRUE(json
.Contains(field
));
41 ASSERT_TRUE(json
[field
].IsBool());
42 ASSERT_EQ(expected
, json
[field
].GetBool());
45 void AssertField(const JSONDocument
& json
, const std::string
& field
,
47 ASSERT_TRUE(json
.Contains(field
));
48 ASSERT_TRUE(json
[field
].IsDouble());
49 ASSERT_DOUBLE_EQ(expected
, json
[field
].GetDouble());
53 class JSONDocumentTest
: public testing::Test
{
59 void AssertSampleJSON(const JSONDocument
& json
) {
60 AssertField(json
, "title", std::string("json"));
61 AssertField(json
, "type", std::string("object"));
63 ASSERT_TRUE(json
.Contains("properties"));
64 ASSERT_TRUE(json
["properties"].Contains("flags"));
65 ASSERT_TRUE(json
["properties"]["flags"].IsArray());
66 ASSERT_EQ(3u, json
["properties"]["flags"].Count());
67 ASSERT_TRUE(json
["properties"]["flags"][0].IsInt64());
68 ASSERT_EQ(10, json
["properties"]["flags"][0].GetInt64());
69 ASSERT_TRUE(json
["properties"]["flags"][1].IsString());
70 ASSERT_EQ("parse", json
["properties"]["flags"][1].GetString());
71 ASSERT_TRUE(json
["properties"]["flags"][2].IsObject());
72 AssertField(json
["properties"]["flags"][2], "tag", std::string("no"));
73 AssertField(json
["properties"]["flags"][2], std::string("status"));
74 AssertField(json
["properties"], "age", 110.5e-4);
75 AssertField(json
["properties"], "depth", static_cast<int64_t>(-10));
77 std::set
<std::string
> expected({"flags", "age", "depth"});
78 for (auto item
: json
["properties"].Items()) {
79 auto iter
= expected
.find(item
.first
);
80 ASSERT_TRUE(iter
!= expected
.end());
83 ASSERT_EQ(0U, expected
.size());
84 ASSERT_TRUE(json
.Contains("latlong"));
85 ASSERT_TRUE(json
["latlong"].IsArray());
86 ASSERT_EQ(2u, json
["latlong"].Count());
87 ASSERT_TRUE(json
["latlong"][0].IsDouble());
88 ASSERT_EQ(53.25, json
["latlong"][0].GetDouble());
89 ASSERT_TRUE(json
["latlong"][1].IsDouble());
90 ASSERT_EQ(43.75, json
["latlong"][1].GetDouble());
91 AssertField(json
, "enabled", true);
94 const std::string kSampleJSON
=
95 "{ \"title\" : \"json\", \"type\" : \"object\", \"properties\" : { "
96 "\"flags\": [10, \"parse\", {\"tag\": \"no\", \"status\": null}], "
97 "\"age\": 110.5e-4, \"depth\": -10 }, \"latlong\": [53.25, 43.75], "
98 "\"enabled\": true }";
100 const std::string kSampleJSONDifferent
=
101 "{ \"title\" : \"json\", \"type\" : \"object\", \"properties\" : { "
102 "\"flags\": [10, \"parse\", {\"tag\": \"no\", \"status\": 2}], "
103 "\"age\": 110.5e-4, \"depth\": -10 }, \"latlong\": [53.25, 43.75], "
104 "\"enabled\": true }";
109 TEST_F(JSONDocumentTest
, MakeNullTest
) {
111 ASSERT_TRUE(x
.IsNull());
112 ASSERT_TRUE(x
.IsOwner());
113 ASSERT_TRUE(!x
.IsBool());
116 TEST_F(JSONDocumentTest
, MakeBoolTest
) {
118 JSONDocument
x(true);
119 ASSERT_TRUE(x
.IsOwner());
120 ASSERT_TRUE(x
.IsBool());
121 ASSERT_TRUE(!x
.IsInt64());
122 ASSERT_EQ(x
.GetBool(), true);
126 JSONDocument
x(false);
127 ASSERT_TRUE(x
.IsOwner());
128 ASSERT_TRUE(x
.IsBool());
129 ASSERT_TRUE(!x
.IsInt64());
130 ASSERT_EQ(x
.GetBool(), false);
134 TEST_F(JSONDocumentTest
, MakeInt64Test
) {
135 JSONDocument
x(static_cast<int64_t>(16));
136 ASSERT_TRUE(x
.IsInt64());
137 ASSERT_TRUE(x
.IsInt64());
138 ASSERT_TRUE(!x
.IsBool());
139 ASSERT_TRUE(x
.IsOwner());
140 ASSERT_EQ(x
.GetInt64(), 16);
143 TEST_F(JSONDocumentTest
, MakeStringTest
) {
144 JSONDocument
x("string");
145 ASSERT_TRUE(x
.IsOwner());
146 ASSERT_TRUE(x
.IsString());
147 ASSERT_TRUE(!x
.IsBool());
148 ASSERT_EQ(x
.GetString(), "string");
151 TEST_F(JSONDocumentTest
, MakeDoubleTest
) {
153 ASSERT_TRUE(x
.IsOwner());
154 ASSERT_TRUE(x
.IsDouble());
155 ASSERT_TRUE(!x
.IsBool());
156 ASSERT_EQ(x
.GetDouble(), 5.6);
159 TEST_F(JSONDocumentTest
, MakeByTypeTest
) {
161 JSONDocument
x(JSONDocument::kNull
);
162 ASSERT_TRUE(x
.IsNull());
165 JSONDocument
x(JSONDocument::kBool
);
166 ASSERT_TRUE(x
.IsBool());
169 JSONDocument
x(JSONDocument::kString
);
170 ASSERT_TRUE(x
.IsString());
173 JSONDocument
x(JSONDocument::kInt64
);
174 ASSERT_TRUE(x
.IsInt64());
177 JSONDocument
x(JSONDocument::kDouble
);
178 ASSERT_TRUE(x
.IsDouble());
181 JSONDocument
x(JSONDocument::kObject
);
182 ASSERT_TRUE(x
.IsObject());
185 JSONDocument
x(JSONDocument::kArray
);
186 ASSERT_TRUE(x
.IsArray());
190 TEST_F(JSONDocumentTest
, Parsing
) {
191 std::unique_ptr
<JSONDocument
> parsed_json(
192 JSONDocument::ParseJSON(kSampleJSON
.c_str()));
193 ASSERT_TRUE(parsed_json
->IsOwner());
194 ASSERT_TRUE(parsed_json
!= nullptr);
195 AssertSampleJSON(*parsed_json
);
198 JSONDocument
copied_json_document(*parsed_json
);
199 AssertSampleJSON(copied_json_document
);
200 ASSERT_TRUE(copied_json_document
== *parsed_json
);
202 std::unique_ptr
<JSONDocument
> parsed_different_sample(
203 JSONDocument::ParseJSON(kSampleJSONDifferent
.c_str()));
204 ASSERT_TRUE(parsed_different_sample
!= nullptr);
205 ASSERT_TRUE(!(*parsed_different_sample
== copied_json_document
));
208 const std::string kFaultyJSON
=
209 kSampleJSON
.substr(0, kSampleJSON
.size() - 10);
210 ASSERT_TRUE(JSONDocument::ParseJSON(kFaultyJSON
.c_str()) == nullptr);
213 TEST_F(JSONDocumentTest
, Serialization
) {
214 std::unique_ptr
<JSONDocument
> parsed_json(
215 JSONDocument::ParseJSON(kSampleJSON
.c_str()));
216 ASSERT_TRUE(parsed_json
!= nullptr);
217 ASSERT_TRUE(parsed_json
->IsOwner());
218 std::string serialized
;
219 parsed_json
->Serialize(&serialized
);
221 std::unique_ptr
<JSONDocument
> deserialized_json(
222 JSONDocument::Deserialize(Slice(serialized
)));
223 ASSERT_TRUE(deserialized_json
!= nullptr);
224 AssertSampleJSON(*deserialized_json
);
226 // deserialization failure
227 ASSERT_TRUE(JSONDocument::Deserialize(
228 Slice(serialized
.data(), serialized
.size() - 10)) == nullptr);
231 TEST_F(JSONDocumentTest
, OperatorEqualsTest
) {
233 ASSERT_TRUE(JSONDocument() == JSONDocument());
236 ASSERT_TRUE(JSONDocument(false) != JSONDocument());
237 ASSERT_TRUE(JSONDocument(false) == JSONDocument(false));
238 ASSERT_TRUE(JSONDocument(true) == JSONDocument(true));
239 ASSERT_TRUE(JSONDocument(false) != JSONDocument(true));
242 ASSERT_TRUE(JSONDocument("test") != JSONDocument());
243 ASSERT_TRUE(JSONDocument("test") == JSONDocument("test"));
246 ASSERT_TRUE(JSONDocument(static_cast<int64_t>(15)) != JSONDocument());
247 ASSERT_TRUE(JSONDocument(static_cast<int64_t>(15)) !=
248 JSONDocument(static_cast<int64_t>(14)));
249 ASSERT_TRUE(JSONDocument(static_cast<int64_t>(15)) ==
250 JSONDocument(static_cast<int64_t>(15)));
252 unique_ptr
<JSONDocument
> arrayWithInt8Doc(JSONDocument::ParseJSON("[8]"));
253 ASSERT_TRUE(arrayWithInt8Doc
!= nullptr);
254 ASSERT_TRUE(arrayWithInt8Doc
->IsArray());
255 ASSERT_TRUE((*arrayWithInt8Doc
)[0].IsInt64());
256 ASSERT_TRUE((*arrayWithInt8Doc
)[0] == JSONDocument(static_cast<int64_t>(8)));
258 unique_ptr
<JSONDocument
> arrayWithInt16Doc(JSONDocument::ParseJSON("[512]"));
259 ASSERT_TRUE(arrayWithInt16Doc
!= nullptr);
260 ASSERT_TRUE(arrayWithInt16Doc
->IsArray());
261 ASSERT_TRUE((*arrayWithInt16Doc
)[0].IsInt64());
262 ASSERT_TRUE((*arrayWithInt16Doc
)[0] ==
263 JSONDocument(static_cast<int64_t>(512)));
265 unique_ptr
<JSONDocument
> arrayWithInt32Doc(
266 JSONDocument::ParseJSON("[1000000]"));
267 ASSERT_TRUE(arrayWithInt32Doc
!= nullptr);
268 ASSERT_TRUE(arrayWithInt32Doc
->IsArray());
269 ASSERT_TRUE((*arrayWithInt32Doc
)[0].IsInt64());
270 ASSERT_TRUE((*arrayWithInt32Doc
)[0] ==
271 JSONDocument(static_cast<int64_t>(1000000)));
274 ASSERT_TRUE(JSONDocument(15.) != JSONDocument());
275 ASSERT_TRUE(JSONDocument(15.) != JSONDocument(14.));
276 ASSERT_TRUE(JSONDocument(15.) == JSONDocument(15.));
279 TEST_F(JSONDocumentTest
, JSONDocumentBuilderTest
) {
280 unique_ptr
<JSONDocument
> parsedArray(
281 JSONDocument::ParseJSON("[1, [123, \"a\", \"b\"], {\"b\":\"c\"}]"));
282 ASSERT_TRUE(parsedArray
!= nullptr);
284 JSONDocumentBuilder builder
;
285 ASSERT_TRUE(builder
.WriteStartArray());
286 ASSERT_TRUE(builder
.WriteJSONDocument(1));
288 ASSERT_TRUE(builder
.WriteStartArray());
289 ASSERT_TRUE(builder
.WriteJSONDocument(123));
290 ASSERT_TRUE(builder
.WriteJSONDocument("a"));
291 ASSERT_TRUE(builder
.WriteJSONDocument("b"));
292 ASSERT_TRUE(builder
.WriteEndArray());
294 ASSERT_TRUE(builder
.WriteStartObject());
295 ASSERT_TRUE(builder
.WriteKeyValue("b", "c"));
296 ASSERT_TRUE(builder
.WriteEndObject());
298 ASSERT_TRUE(builder
.WriteEndArray());
300 ASSERT_TRUE(*parsedArray
== builder
.GetJSONDocument());
303 TEST_F(JSONDocumentTest
, OwnershipTest
) {
304 std::unique_ptr
<JSONDocument
> parsed(
305 JSONDocument::ParseJSON(kSampleJSON
.c_str()));
306 ASSERT_TRUE(parsed
!= nullptr);
307 ASSERT_TRUE(parsed
->IsOwner());
309 // Copy constructor from owner -> owner
310 JSONDocument
copy_constructor(*parsed
);
311 ASSERT_TRUE(copy_constructor
.IsOwner());
313 // Copy constructor from non-owner -> non-owner
314 JSONDocument
non_owner((*parsed
)["properties"]);
315 ASSERT_TRUE(!non_owner
.IsOwner());
317 // Move constructor from owner -> owner
318 JSONDocument
moved_from_owner(std::move(copy_constructor
));
319 ASSERT_TRUE(moved_from_owner
.IsOwner());
321 // Move constructor from non-owner -> non-owner
322 JSONDocument
moved_from_non_owner(std::move(non_owner
));
323 ASSERT_TRUE(!moved_from_non_owner
.IsOwner());
326 } // namespace rocksdb
328 int main(int argc
, char** argv
) {
329 ::testing::InitGoogleTest(&argc
, argv
);
330 return RUN_ALL_TESTS();
336 int main(int argc
, char** argv
) {
337 fprintf(stderr
, "SKIPPED as JSONDocument is not supported in ROCKSDB_LITE\n");
341 #endif // !ROCKSDB_LITE