scan-test.cc 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Formatting library for C++ - scanning API test
  2. //
  3. // Copyright (c) 2019 - present, Victor Zverovich
  4. // All rights reserved.
  5. //
  6. // For the license information refer to format.h.
  7. #include "scan.h"
  8. #include <time.h>
  9. #include <climits>
  10. #include "gmock/gmock.h"
  11. #include "gtest-extra.h"
  12. TEST(scan_test, read_text) {
  13. auto s = fmt::string_view("foo");
  14. auto end = fmt::scan(s, "foo");
  15. EXPECT_EQ(end, s.end());
  16. EXPECT_THROW_MSG(fmt::scan("fob", "foo"), fmt::format_error, "invalid input");
  17. }
  18. TEST(scan_test, read_int) {
  19. auto n = int();
  20. fmt::scan("42", "{}", n);
  21. EXPECT_EQ(n, 42);
  22. fmt::scan("-42", "{}", n);
  23. EXPECT_EQ(n, -42);
  24. }
  25. TEST(scan_test, read_longlong) {
  26. long long n = 0;
  27. fmt::scan("42", "{}", n);
  28. EXPECT_EQ(n, 42);
  29. fmt::scan("-42", "{}", n);
  30. EXPECT_EQ(n, -42);
  31. }
  32. TEST(scan_test, read_uint) {
  33. auto n = unsigned();
  34. fmt::scan("42", "{}", n);
  35. EXPECT_EQ(n, 42);
  36. EXPECT_THROW_MSG(fmt::scan("-42", "{}", n), fmt::format_error,
  37. "invalid input");
  38. }
  39. TEST(scan_test, read_ulonglong) {
  40. unsigned long long n = 0;
  41. fmt::scan("42", "{}", n);
  42. EXPECT_EQ(n, 42);
  43. EXPECT_THROW_MSG(fmt::scan("-42", "{}", n), fmt::format_error,
  44. "invalid input");
  45. }
  46. TEST(scan_test, read_string) {
  47. auto s = std::string();
  48. fmt::scan("foo", "{}", s);
  49. EXPECT_EQ(s, "foo");
  50. }
  51. TEST(scan_test, read_string_view) {
  52. auto s = fmt::string_view();
  53. fmt::scan("foo", "{}", s);
  54. EXPECT_EQ(s, "foo");
  55. }
  56. #ifndef _WIN32
  57. namespace fmt {
  58. template <> struct scanner<tm> {
  59. std::string format;
  60. scan_parse_context::iterator parse(scan_parse_context& ctx) {
  61. auto it = ctx.begin();
  62. if (it != ctx.end() && *it == ':') ++it;
  63. auto end = it;
  64. while (end != ctx.end() && *end != '}') ++end;
  65. format.reserve(detail::to_unsigned(end - it + 1));
  66. format.append(it, end);
  67. format.push_back('\0');
  68. return end;
  69. }
  70. template <class ScanContext>
  71. typename ScanContext::iterator scan(tm& t, ScanContext& ctx) {
  72. auto result = strptime(ctx.begin(), format.c_str(), &t);
  73. if (!result) throw format_error("failed to parse time");
  74. return result;
  75. }
  76. };
  77. } // namespace fmt
  78. TEST(scan_test, read_custom) {
  79. auto input = "Date: 1985-10-25";
  80. auto t = tm();
  81. fmt::scan(input, "Date: {0:%Y-%m-%d}", t);
  82. EXPECT_EQ(t.tm_year, 85);
  83. EXPECT_EQ(t.tm_mon, 9);
  84. EXPECT_EQ(t.tm_mday, 25);
  85. }
  86. #endif
  87. TEST(scan_test, invalid_format) {
  88. EXPECT_THROW_MSG(fmt::scan("", "{}"), fmt::format_error,
  89. "argument index out of range");
  90. EXPECT_THROW_MSG(fmt::scan("", "{"), fmt::format_error,
  91. "invalid format string");
  92. }
  93. TEST(scan_test, example) {
  94. auto key = std::string();
  95. auto value = int();
  96. fmt::scan("answer = 42", "{} = {}", key, value);
  97. EXPECT_EQ(key, "answer");
  98. EXPECT_EQ(value, 42);
  99. }