Futex::futexWait returns FutexResult
[folly.git] / folly / test / FormatOtherTest.cpp
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/Format.h>
18
19 #include <glog/logging.h>
20
21 #include <folly/FBVector.h>
22 #include <folly/FileUtil.h>
23 #include <folly/Portability.h>
24 #include <folly/dynamic.h>
25 #include <folly/json.h>
26 #include <folly/portability/GTest.h>
27 #include <folly/small_vector.h>
28
29 using namespace folly;
30
31 TEST(FormatOther, file) {
32   // Test writing to FILE. I'd use open_memstream but that's not available
33   // outside of Linux (even though it's in POSIX.1-2008).
34   {
35     int fds[2];
36     CHECK_ERR(pipe(fds));
37     SCOPE_EXIT {
38       // fclose on Windows automatically closes the underlying
39       // file descriptor.
40       if (!kIsWindows) {
41         closeNoInt(fds[1]);
42       }
43     };
44     {
45       FILE* fp = fdopen(fds[1], "wb");
46       PCHECK(fp);
47       SCOPE_EXIT { fclose(fp); };
48       writeTo(fp, format("{} {}", 42, 23));  // <= 512 bytes (PIPE_BUF)
49     }
50
51     char buf[512];
52     ssize_t n = readFull(fds[0], buf, sizeof(buf));
53     CHECK_GE(n, 0);
54
55     EXPECT_EQ("42 23", std::string(buf, n));
56   }
57 }
58
59 TEST(FormatOther, dynamic) {
60   auto dyn = parseJson(
61       "{\n"
62       "  \"hello\": \"world\",\n"
63       "  \"x\": [20, 30],\n"
64       "  \"y\": {\"a\" : 42}\n"
65       "}");
66
67   EXPECT_EQ("world", sformat("{0[hello]}", dyn));
68   EXPECT_THROW(sformat("{0[none]}", dyn), std::out_of_range);
69   EXPECT_EQ("world", sformat("{0[hello]}", defaulted(dyn, "meow")));
70   EXPECT_EQ("meow", sformat("{0[none]}", defaulted(dyn, "meow")));
71
72   EXPECT_EQ("20", sformat("{0[x.0]}", dyn));
73   EXPECT_THROW(sformat("{0[x.2]}", dyn), std::out_of_range);
74
75   // No support for "deep" defaulting (dyn["x"] is not defaulted)
76   auto v = dyn.at("x");
77   EXPECT_EQ("20", sformat("{0[0]}", v));
78   EXPECT_THROW(sformat("{0[2]}", v), std::out_of_range);
79   EXPECT_EQ("20", sformat("{0[0]}", defaulted(v, 42)));
80   EXPECT_EQ("42", sformat("{0[2]}", defaulted(v, 42)));
81
82   EXPECT_EQ("42", sformat("{0[y.a]}", dyn));
83
84   EXPECT_EQ("(null)", sformat("{}", dynamic(nullptr)));
85 }
86
87 namespace {
88
89 template <class T>
90 void testFormatSeq() {
91   T v{10, 20, 30};
92   EXPECT_EQ("30 10", sformat("{0[2]} {0[0]}", v));
93   EXPECT_EQ("0020", sformat("{0[1]:04}", v));
94   EXPECT_EQ("0020", svformat("{1:04}", v));
95   EXPECT_EQ("10 20", svformat("{} {}", v));
96   EXPECT_EQ("10 20 0030", svformat("{} {} {:04}", v));
97 }
98
99 } // namespace
100
101 TEST(FormatOther, fbvector) {
102   testFormatSeq<fbvector<int>>();
103 }
104
105 TEST(FormatOther, small_vector) {
106   testFormatSeq<small_vector<int, 2>>();
107 }
108
109 int main(int argc, char *argv[]) {
110   testing::InitGoogleTest(&argc, argv);
111   gflags::ParseCommandLineFlags(&argc, &argv, true);
112   return RUN_ALL_TESTS();
113 }