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