FormatOtherTest.cpp 3.1 KB

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