xref: /llvm-project/libcxx/test/std/time/time.syn/formatter_tests.h (revision 6a54dfbfe534276d644d7f9c027f0deeb748dd53)
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef TEST_STD_TIME_TIME_SYN_FORMATTER_TESTS_H
10 #define TEST_STD_TIME_TIME_SYN_FORMATTER_TESTS_H
11 
12 #include "assert_macros.h"
13 #include "concat_macros.h"
14 #include "make_string.h"
15 #include "string_literal.h"
16 #include "test_format_string.h"
17 #include "test_macros.h"
18 
19 #include <algorithm>
20 #include <cassert>
21 #include <iostream>
22 #include <set>
23 #include <string>
24 #include <string_view>
25 
26 #define STR(S) MAKE_STRING(CharT, S)
27 #define SV(S) MAKE_STRING_VIEW(CharT, S)
28 
29 #ifndef TEST_HAS_NO_WIDE_CHARACTERS
30 template <class CharT>
31 using format_context = std::conditional_t<std::same_as<CharT, char>, std::format_context, std::wformat_context>;
32 #else
33 template <class CharT>
34 using format_context = std::format_context;
35 #endif
36 
37 template <class CharT, class... Args>
38 void check(std::basic_string_view<CharT> expected, test_format_string<CharT, Args...> fmt, Args&&... args) {
39   std::basic_string<CharT> out = std::format(fmt, std::forward<Args>(args)...);
40   TEST_REQUIRE(out == expected,
41                TEST_WRITE_CONCATENATED(
42                    "\nFormat string   ", fmt.get(), "\nExpected output ", expected, "\nActual output   ", out, '\n'));
43 }
44 
45 template <class CharT, class... Args>
46 void check(const std::locale& loc,
47            std::basic_string_view<CharT> expected,
48            test_format_string<CharT, Args...> fmt,
49            Args&&... args) {
50   std::basic_string<CharT> out = std::format(loc, fmt, std::forward<Args>(args)...);
51   TEST_REQUIRE(out == expected,
52                TEST_WRITE_CONCATENATED(
53                    "\nFormat string   ", fmt.get(), "\nExpected output ", expected, "\nActual output   ", out, '\n'));
54 }
55 
56 template <class CharT, class... Args>
57 void check_exception([[maybe_unused]] std::string_view what,
58                      [[maybe_unused]] std::basic_string_view<CharT> fmt,
59                      [[maybe_unused]] const Args&... args) {
60   TEST_VALIDATE_EXCEPTION(
61       std::format_error,
62       [&]([[maybe_unused]] const std::format_error& e) {
63         TEST_LIBCPP_REQUIRE(
64             e.what() == what,
65             TEST_WRITE_CONCATENATED(
66                 "\nFormat string   ", fmt, "\nExpected exception ", what, "\nActual exception   ", e.what(), '\n'));
67       },
68       TEST_IGNORE_NODISCARD std::vformat(fmt, std::make_format_args<format_context<CharT>>(args...)));
69 }
70 
71 template <class CharT, class T>
72 void check_invalid_type(const std::set<std::basic_string_view<CharT>>& valid_types,
73                         std::string_view what,
74                         std::basic_string<CharT> type,
75                         const T& arg) {
76   std::basic_string<CharT> fmt{STR("{:%") + type + STR("}")};
77 
78   if (valid_types.contains(std::basic_string_view<CharT>{type})) {
79 #ifndef TEST_HAS_NO_EXCEPTIONS
80     try {
81 #endif
82       TEST_IGNORE_NODISCARD std::vformat(
83           std::basic_string_view<CharT>{fmt}, std::make_format_args<format_context<CharT>>(arg));
84 #ifndef TEST_HAS_NO_EXCEPTIONS
85     } catch (const std::format_error& e) {
86       (void)e;
87       if constexpr (std::same_as<CharT, char>)
88         std::cerr << "\nFormat string        " << fmt << "\nUnexpected exception " << e.what() << '\n';
89       assert(false);
90     }
91 #endif
92   } else {
93     check_exception(what, std::basic_string_view<CharT>{fmt}, arg);
94   }
95 }
96 
97 template <class CharT, class T>
98 void check_invalid_types(const std::set<std::basic_string_view<CharT>>& valid_types, const T& arg) {
99   check_invalid_type(valid_types, "The supplied date time doesn't contain a weekday", STR("a"), arg);
100   check_invalid_type(valid_types, "The supplied date time doesn't contain a weekday", STR("A"), arg);
101   check_invalid_type(valid_types, "The supplied date time doesn't contain a month", STR("b"), arg);
102   check_invalid_type(valid_types, "The supplied date time doesn't contain a month", STR("B"), arg);
103   check_invalid_type(valid_types, "The supplied date time doesn't contain a date and time", STR("c"), arg);
104   check_invalid_type(valid_types, "The supplied date time doesn't contain a year", STR("C"), arg);
105   check_invalid_type(valid_types, "The supplied date time doesn't contain a day", STR("d"), arg);
106   check_invalid_type(valid_types, "The supplied date time doesn't contain a date", STR("D"), arg);
107   check_invalid_type(valid_types, "The supplied date time doesn't contain a day", STR("e"), arg);
108   // E - the modifier is checked separately
109   check_invalid_type(valid_types, "The date time type specifier is invalid", STR("f"), arg);
110   check_invalid_type(valid_types, "The supplied date time doesn't contain a date", STR("F"), arg);
111   check_invalid_type(valid_types, "The supplied date time doesn't contain a date", STR("g"), arg);
112   check_invalid_type(valid_types, "The supplied date time doesn't contain a date", STR("G"), arg);
113   check_invalid_type(valid_types, "The supplied date time doesn't contain a month", STR("h"), arg);
114   check_invalid_type(valid_types, "The supplied date time doesn't contain an hour", STR("H"), arg);
115   check_invalid_type(valid_types, "The date time type specifier is invalid", STR("i"), arg);
116   check_invalid_type(valid_types, "The supplied date time doesn't contain an hour", STR("I"), arg);
117   check_invalid_type(valid_types, "The supplied date time doesn't contain a date or duration", STR("j"), arg);
118   check_invalid_type(valid_types, "The date time type specifier is invalid", STR("J"), arg);
119   check_invalid_type(valid_types, "The date time type specifier is invalid", STR("k"), arg);
120   check_invalid_type(valid_types, "The date time type specifier is invalid", STR("K"), arg);
121   check_invalid_type(valid_types, "The date time type specifier is invalid", STR("l"), arg);
122   check_invalid_type(valid_types, "The date time type specifier is invalid", STR("L"), arg);
123   check_invalid_type(valid_types, "The supplied date time doesn't contain a month", STR("m"), arg);
124   check_invalid_type(valid_types, "The supplied date time doesn't contain a minute", STR("M"), arg);
125   // n - valid
126   check_invalid_type(valid_types, "The date time type specifier is invalid", STR("N"), arg);
127   check_invalid_type(valid_types, "The date time type specifier is invalid", STR("o"), arg);
128   // O - the modifier is checked separately
129   check_invalid_type(valid_types, "The supplied date time doesn't contain an hour", STR("p"), arg);
130   check_invalid_type(valid_types, "The date time type specifier is invalid", STR("P"), arg);
131   check_invalid_type(valid_types, "The supplied date time doesn't contain a duration", STR("q"), arg);
132   check_invalid_type(valid_types, "The supplied date time doesn't contain a duration", STR("Q"), arg);
133   check_invalid_type(valid_types, "The supplied date time doesn't contain a time", STR("r"), arg);
134   check_invalid_type(valid_types, "The supplied date time doesn't contain a time", STR("R"), arg);
135   check_invalid_type(valid_types, "The date time type specifier is invalid", STR("s"), arg);
136   check_invalid_type(valid_types, "The supplied date time doesn't contain a second", STR("S"), arg);
137   // t - valid
138   check_invalid_type(valid_types, "The supplied date time doesn't contain a time", STR("T"), arg);
139   check_invalid_type(valid_types, "The supplied date time doesn't contain a weekday", STR("u"), arg);
140   check_invalid_type(valid_types, "The supplied date time doesn't contain a date", STR("U"), arg);
141   check_invalid_type(valid_types, "The date time type specifier is invalid", STR("v"), arg);
142   check_invalid_type(valid_types, "The supplied date time doesn't contain a date", STR("V"), arg);
143   check_invalid_type(valid_types, "The supplied date time doesn't contain a weekday", STR("w"), arg);
144   check_invalid_type(valid_types, "The supplied date time doesn't contain a date", STR("W"), arg);
145   check_invalid_type(valid_types, "The supplied date time doesn't contain a date", STR("x"), arg);
146   check_invalid_type(valid_types, "The supplied date time doesn't contain a time", STR("X"), arg);
147   check_invalid_type(valid_types, "The supplied date time doesn't contain a year", STR("y"), arg);
148   check_invalid_type(valid_types, "The supplied date time doesn't contain a year", STR("y"), arg);
149   check_invalid_type(valid_types, "The supplied date time doesn't contain a time zone", STR("z"), arg);
150   check_invalid_type(valid_types, "The supplied date time doesn't contain a time zone", STR("Z"), arg);
151 
152   // *** E modifier
153   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Ea"), arg);
154   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EA"), arg);
155   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Eb"), arg);
156   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EB"), arg);
157   check_invalid_type(valid_types, "The supplied date time doesn't contain a date and time", STR("Ec"), arg);
158   check_invalid_type(valid_types, "The supplied date time doesn't contain a year", STR("EC"), arg);
159   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Ed"), arg);
160   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("ED"), arg);
161   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Ee"), arg);
162   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EE"), arg);
163   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Ef"), arg);
164   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EF"), arg);
165   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Eg"), arg);
166   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EG"), arg);
167   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Eh"), arg);
168   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EH"), arg);
169   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Ei"), arg);
170   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EI"), arg);
171   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Ej"), arg);
172   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EJ"), arg);
173   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Ek"), arg);
174   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EK"), arg);
175   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("El"), arg);
176   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EL"), arg);
177   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Em"), arg);
178   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EM"), arg);
179   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("En"), arg);
180   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EN"), arg);
181   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Eo"), arg);
182   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EO"), arg);
183   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Ep"), arg);
184   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EP"), arg);
185   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Eq"), arg);
186   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EQ"), arg);
187   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Er"), arg);
188   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("ER"), arg);
189   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Es"), arg);
190   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("ES"), arg);
191   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Et"), arg);
192   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("ET"), arg);
193   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Eu"), arg);
194   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EU"), arg);
195   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Ev"), arg);
196   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EV"), arg);
197   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("Ew"), arg);
198   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EW"), arg);
199   check_invalid_type(valid_types, "The supplied date time doesn't contain a date", STR("Ex"), arg);
200   check_invalid_type(valid_types, "The supplied date time doesn't contain a time", STR("EX"), arg);
201   check_invalid_type(valid_types, "The supplied date time doesn't contain a year", STR("Ey"), arg);
202   check_invalid_type(valid_types, "The supplied date time doesn't contain a year", STR("EY"), arg);
203   check_invalid_type(valid_types, "The supplied date time doesn't contain a time zone", STR("Ez"), arg);
204   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("EZ"), arg);
205   check_invalid_type(valid_types, "The date time type specifier for modifier E is invalid", STR("E%"), arg);
206 
207   // *** O modifier
208   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Oa"), arg);
209   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OA"), arg);
210   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Ob"), arg);
211   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OB"), arg);
212   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Oc"), arg);
213   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OC"), arg);
214   check_invalid_type(valid_types, "The supplied date time doesn't contain a day", STR("Od"), arg);
215   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OD"), arg);
216   check_invalid_type(valid_types, "The supplied date time doesn't contain a day", STR("Oe"), arg);
217   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OE"), arg);
218   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Of"), arg);
219   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OF"), arg);
220   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Og"), arg);
221   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OG"), arg);
222   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Oh"), arg);
223   check_invalid_type(valid_types, "The supplied date time doesn't contain an hour", STR("OH"), arg);
224   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Oi"), arg);
225   check_invalid_type(valid_types, "The supplied date time doesn't contain an hour", STR("OI"), arg);
226   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Oj"), arg);
227   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OJ"), arg);
228   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Ok"), arg);
229   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OK"), arg);
230   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Ol"), arg);
231   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OL"), arg);
232   check_invalid_type(valid_types, "The supplied date time doesn't contain a month", STR("Om"), arg);
233   check_invalid_type(valid_types, "The supplied date time doesn't contain a minute", STR("OM"), arg);
234   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("On"), arg);
235   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("ON"), arg);
236   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Oo"), arg);
237   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OO"), arg);
238   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Op"), arg);
239   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OP"), arg);
240   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Oq"), arg);
241   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OQ"), arg);
242   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Or"), arg);
243   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OR"), arg);
244   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Os"), arg);
245   check_invalid_type(valid_types, "The supplied date time doesn't contain a second", STR("OS"), arg);
246   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Ot"), arg);
247   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OT"), arg);
248   check_invalid_type(valid_types, "The supplied date time doesn't contain a weekday", STR("Ou"), arg);
249   check_invalid_type(valid_types, "The supplied date time doesn't contain a date", STR("OU"), arg);
250   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Ov"), arg);
251   check_invalid_type(valid_types, "The supplied date time doesn't contain a date", STR("OV"), arg);
252   check_invalid_type(valid_types, "The supplied date time doesn't contain a weekday", STR("Ow"), arg);
253   check_invalid_type(valid_types, "The supplied date time doesn't contain a date", STR("OW"), arg);
254   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("Ox"), arg);
255   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OX"), arg);
256   check_invalid_type(valid_types, "The supplied date time doesn't contain a year", STR("Oy"), arg);
257   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OY"), arg);
258   check_invalid_type(valid_types, "The supplied date time doesn't contain a time zone", STR("Oz"), arg);
259   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("OZ"), arg);
260   check_invalid_type(valid_types, "The date time type specifier for modifier O is invalid", STR("O%"), arg);
261 }
262 
263 #endif // TEST_STD_TIME_TIME_SYN_FORMATTER_TESTS_H
264