• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
8 #include "scan.h"
9 
10 #include <time.h>
11 
12 #include <climits>
13 
14 #include "gmock.h"
15 #include "gtest-extra.h"
16 
TEST(ScanTest,ReadText)17 TEST(ScanTest, ReadText) {
18   fmt::string_view s = "foo";
19   auto end = fmt::scan(s, "foo");
20   EXPECT_EQ(end, s.end());
21   EXPECT_THROW_MSG(fmt::scan("fob", "foo"), fmt::format_error, "invalid input");
22 }
23 
TEST(ScanTest,ReadInt)24 TEST(ScanTest, ReadInt) {
25   int n = 0;
26   fmt::scan("42", "{}", n);
27   EXPECT_EQ(n, 42);
28   fmt::scan("-42", "{}", n);
29   EXPECT_EQ(n, -42);
30 }
31 
TEST(ScanTest,ReadLongLong)32 TEST(ScanTest, ReadLongLong) {
33   long long n = 0;
34   fmt::scan("42", "{}", n);
35   EXPECT_EQ(n, 42);
36   fmt::scan("-42", "{}", n);
37   EXPECT_EQ(n, -42);
38 }
39 
TEST(ScanTest,ReadUInt)40 TEST(ScanTest, ReadUInt) {
41   unsigned n = 0;
42   fmt::scan("42", "{}", n);
43   EXPECT_EQ(n, 42);
44   EXPECT_THROW_MSG(fmt::scan("-42", "{}", n), fmt::format_error,
45                    "invalid input");
46 }
47 
TEST(ScanTest,ReadULongLong)48 TEST(ScanTest, ReadULongLong) {
49   unsigned long long n = 0;
50   fmt::scan("42", "{}", n);
51   EXPECT_EQ(n, 42);
52   EXPECT_THROW_MSG(fmt::scan("-42", "{}", n), fmt::format_error,
53                    "invalid input");
54 }
55 
TEST(ScanTest,ReadString)56 TEST(ScanTest, ReadString) {
57   std::string s;
58   fmt::scan("foo", "{}", s);
59   EXPECT_EQ(s, "foo");
60 }
61 
TEST(ScanTest,ReadStringView)62 TEST(ScanTest, ReadStringView) {
63   fmt::string_view s;
64   fmt::scan("foo", "{}", s);
65   EXPECT_EQ(s, "foo");
66 }
67 
68 #ifndef _WIN32
69 namespace fmt {
70 template <> struct scanner<tm> {
71   std::string format;
72 
parsefmt::scanner73   scan_parse_context::iterator parse(scan_parse_context& ctx) {
74     auto it = ctx.begin();
75     if (it != ctx.end() && *it == ':') ++it;
76     auto end = it;
77     while (end != ctx.end() && *end != '}') ++end;
78     format.reserve(detail::to_unsigned(end - it + 1));
79     format.append(it, end);
80     format.push_back('\0');
81     return end;
82   }
83 
84   template <class ScanContext>
scanfmt::scanner85   typename ScanContext::iterator scan(tm& t, ScanContext& ctx) {
86     auto result = strptime(ctx.begin(), format.c_str(), &t);
87     if (!result) throw format_error("failed to parse time");
88     return result;
89   }
90 };
91 }  // namespace fmt
92 
TEST(ScanTest,ReadCustom)93 TEST(ScanTest, ReadCustom) {
94   const char* input = "Date: 1985-10-25";
95   auto t = tm();
96   fmt::scan(input, "Date: {0:%Y-%m-%d}", t);
97   EXPECT_EQ(t.tm_year, 85);
98   EXPECT_EQ(t.tm_mon, 9);
99   EXPECT_EQ(t.tm_mday, 25);
100 }
101 #endif
102 
TEST(ScanTest,InvalidFormat)103 TEST(ScanTest, InvalidFormat) {
104   EXPECT_THROW_MSG(fmt::scan("", "{}"), fmt::format_error,
105                    "argument index out of range");
106   EXPECT_THROW_MSG(fmt::scan("", "{"), fmt::format_error,
107                    "invalid format string");
108 }
109 
TEST(ScanTest,Example)110 TEST(ScanTest, Example) {
111   std::string key;
112   int value;
113   fmt::scan("answer = 42", "{} = {}", key, value);
114   EXPECT_EQ(key, "answer");
115   EXPECT_EQ(value, 42);
116 }
117