1/*
2 * Copyright 2015-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/gen/Base.h>
20#include <folly/json.h>
21#include <folly/portability/GFlags.h>
22#include <folly/portability/GTest.h>
23
24#include <iostream>
25
26using folly::dynamic;
27using folly::TypeError;
28
29TEST(Dynamic, ArrayGenerator) {
30 // Make sure arrays can be used with folly::gen.
31 using namespace folly::gen;
32 dynamic arr = dynamic::array(1, 2, 3, 4);
33 EXPECT_EQ(from(arr) | take(3) | member(&dynamic::asInt) | sum, 6);
34}
35
36TEST(Dynamic, StringPtrs) {
37 dynamic str = "12.0";
38 dynamic num = 12.0;
39 dynamic nullStr = folly::parseJson("\"foo\\u0000bar\"");
40
41 EXPECT_EQ(0, strcmp(str.c_str(), "12.0"));
42 EXPECT_EQ(0, strncmp(str.data(), "12.0", str.asString().length()));
43 EXPECT_EQ(str.stringPiece(), "12.0");
44
45 EXPECT_THROW(num.c_str(), TypeError);
46 EXPECT_THROW(num.data(), TypeError);
47 EXPECT_THROW(num.stringPiece(), TypeError);
48
49 EXPECT_EQ(nullStr.stringPiece(), folly::StringPiece("foo\0bar", 7));
50
51 nullStr.getString()[3] = '|';
52 EXPECT_EQ(nullStr.stringPiece(), "foo|bar");
53}
54
55TEST(Dynamic, Getters) {
56 dynamic dStr = folly::parseJson("\"foo\\u0000bar\"");
57 dynamic dInt = 1;
58 dynamic dDouble = 0.5;
59 dynamic dBool = true;
60
61 EXPECT_EQ(dStr.getString(), std::string("foo\0bar", 7));
62 EXPECT_EQ(dInt.getInt(), 1);
63 EXPECT_EQ(dDouble.getDouble(), 0.5);
64 EXPECT_EQ(dBool.getBool(), true);
65
66 dStr.getString()[3] = '|';
67 EXPECT_EQ(dStr.getString(), "foo|bar");
68
69 dInt.getInt() = 2;
70 EXPECT_EQ(dInt.getInt(), 2);
71
72 dDouble.getDouble() = 0.7;
73 EXPECT_EQ(dDouble.getDouble(), 0.7);
74
75 dBool.getBool() = false;
76 EXPECT_EQ(dBool.getBool(), false);
77
78 EXPECT_THROW(dStr.getInt(), TypeError);
79 EXPECT_THROW(dStr.getDouble(), TypeError);
80 EXPECT_THROW(dStr.getBool(), TypeError);
81
82 EXPECT_THROW(dInt.getString(), TypeError);
83 EXPECT_THROW(dInt.getDouble(), TypeError);
84 EXPECT_THROW(dInt.getBool(), TypeError);
85
86 EXPECT_THROW(dDouble.getString(), TypeError);
87 EXPECT_THROW(dDouble.getInt(), TypeError);
88 EXPECT_THROW(dDouble.getBool(), TypeError);
89
90 EXPECT_THROW(dBool.getString(), TypeError);
91 EXPECT_THROW(dBool.getInt(), TypeError);
92 EXPECT_THROW(dBool.getDouble(), TypeError);
93}
94
95TEST(Dynamic, FormattedIO) {
96 std::ostringstream out;
97 dynamic doubl = 123.33;
98 dynamic dint = 12;
99 out << "0x" << std::hex << ++dint << ' ' << std::setprecision(1) << doubl
100 << '\n';
101 EXPECT_EQ(out.str(), "0xd 1e+02\n");
102
103 out.str("");
104 dynamic arrr = dynamic::array(1, 2, 3);
105 out << arrr;
106 EXPECT_EQ(out.str(), "[1,2,3]");
107
108 out.str("");
109 dynamic objy = dynamic::object("a", 12);
110 out << objy;
111 EXPECT_EQ(out.str(), R"({"a":12})");
112
113 out.str("");
114 dynamic objy2 = dynamic::array(
115 objy, dynamic::object(12, "str"), dynamic::object(true, false));
116 out << objy2;
117 EXPECT_EQ(out.str(), R"([{"a":12},{12:"str"},{true:false}])");
118}
119
120int main(int argc, char** argv) {
121 testing::InitGoogleTest(&argc, argv);
122 gflags::ParseCommandLineFlags(&argc, &argv, true);
123 return RUN_ALL_TESTS();
124}
125