Mercurial > minori
comparison dep/fmt/test/scan-test.cc @ 343:1faa72660932
*: transfer back to cmake from autotools
autotools just made lots of things more complicated than
they should have and many things broke (i.e. translations)
| author | Paper <paper@paper.us.eu.org> |
|---|---|
| date | Thu, 20 Jun 2024 05:56:06 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 342:adb79bdde329 | 343:1faa72660932 |
|---|---|
| 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 #include <thread> | |
| 14 | |
| 15 #include "fmt/os.h" | |
| 16 #include "gmock/gmock.h" | |
| 17 #include "gtest-extra.h" | |
| 18 | |
| 19 TEST(scan_test, read_text) { | |
| 20 fmt::string_view s = "foo"; | |
| 21 auto end = fmt::scan(s, "foo"); | |
| 22 EXPECT_EQ(end, s.end()); | |
| 23 EXPECT_THROW_MSG(fmt::scan("fob", "foo"), fmt::format_error, "invalid input"); | |
| 24 } | |
| 25 | |
| 26 TEST(scan_test, read_int) { | |
| 27 int n = 0; | |
| 28 fmt::scan("42", "{}", n); | |
| 29 EXPECT_EQ(n, 42); | |
| 30 fmt::scan("-42", "{}", n); | |
| 31 EXPECT_EQ(n, -42); | |
| 32 fmt::scan("42", "{:}", n); | |
| 33 EXPECT_EQ(n, 42); | |
| 34 EXPECT_THROW_MSG(fmt::scan(std::to_string(INT_MAX + 1u), "{}", n), | |
| 35 fmt::format_error, "number is too big"); | |
| 36 } | |
| 37 | |
| 38 TEST(scan_test, read_longlong) { | |
| 39 long long n = 0; | |
| 40 fmt::scan("42", "{}", n); | |
| 41 EXPECT_EQ(n, 42); | |
| 42 fmt::scan("-42", "{}", n); | |
| 43 EXPECT_EQ(n, -42); | |
| 44 } | |
| 45 | |
| 46 TEST(scan_test, read_uint) { | |
| 47 unsigned 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 | |
| 54 TEST(scan_test, read_ulonglong) { | |
| 55 unsigned long long n = 0; | |
| 56 fmt::scan("42", "{}", n); | |
| 57 EXPECT_EQ(n, 42); | |
| 58 EXPECT_THROW_MSG(fmt::scan("-42", "{}", n), fmt::format_error, | |
| 59 "invalid input"); | |
| 60 } | |
| 61 | |
| 62 TEST(scan_test, read_hex) { | |
| 63 unsigned n = 0; | |
| 64 fmt::scan("2a", "{:x}", n); | |
| 65 EXPECT_EQ(n, 42); | |
| 66 auto num_digits = std::numeric_limits<unsigned>::digits / 4; | |
| 67 EXPECT_THROW_MSG(fmt::scan(fmt::format("1{:0{}}", 0, num_digits), "{:x}", n), | |
| 68 fmt::format_error, "number is too big"); | |
| 69 } | |
| 70 | |
| 71 TEST(scan_test, read_string) { | |
| 72 std::string s; | |
| 73 fmt::scan("foo", "{}", s); | |
| 74 EXPECT_EQ(s, "foo"); | |
| 75 } | |
| 76 | |
| 77 TEST(scan_test, read_string_view) { | |
| 78 fmt::string_view s; | |
| 79 fmt::scan("foo", "{}", s); | |
| 80 EXPECT_EQ(s, "foo"); | |
| 81 } | |
| 82 | |
| 83 TEST(scan_test, separator) { | |
| 84 int n1 = 0, n2 = 0; | |
| 85 fmt::scan("10 20", "{} {}", n1, n2); | |
| 86 EXPECT_EQ(n1, 10); | |
| 87 EXPECT_EQ(n2, 20); | |
| 88 } | |
| 89 | |
| 90 struct num { | |
| 91 int value; | |
| 92 }; | |
| 93 | |
| 94 namespace fmt { | |
| 95 template <> struct scanner<num> { | |
| 96 bool hex = false; | |
| 97 | |
| 98 auto parse(scan_parse_context& ctx) -> scan_parse_context::iterator { | |
| 99 auto it = ctx.begin(), end = ctx.end(); | |
| 100 if (it != end && *it == 'x') hex = true; | |
| 101 if (it != end && *it != '}') throw_format_error("invalid format"); | |
| 102 return it; | |
| 103 } | |
| 104 | |
| 105 template <class ScanContext> | |
| 106 auto scan(num& n, ScanContext& ctx) const -> typename ScanContext::iterator { | |
| 107 // TODO: handle specifier | |
| 108 return fmt::scan(ctx, "{}", n.value); | |
| 109 } | |
| 110 }; | |
| 111 } // namespace fmt | |
| 112 | |
| 113 TEST(scan_test, read_custom) { | |
| 114 auto input = "42"; | |
| 115 auto n = num(); | |
| 116 fmt::scan(input, "{:}", n); | |
| 117 EXPECT_EQ(n.value, 42); | |
| 118 } | |
| 119 | |
| 120 TEST(scan_test, invalid_format) { | |
| 121 EXPECT_THROW_MSG(fmt::scan("", "{}"), fmt::format_error, | |
| 122 "argument index out of range"); | |
| 123 EXPECT_THROW_MSG(fmt::scan("", "{"), fmt::format_error, | |
| 124 "invalid format string"); | |
| 125 } | |
| 126 | |
| 127 TEST(scan_test, example) { | |
| 128 std::string key; | |
| 129 int value = 0; | |
| 130 fmt::scan("answer = 42", "{} = {}", key, value); | |
| 131 EXPECT_EQ(key, "answer"); | |
| 132 EXPECT_EQ(value, 42); | |
| 133 } | |
| 134 | |
| 135 TEST(scan_test, end_of_input) { | |
| 136 int value = 0; | |
| 137 fmt::scan("", "{}", value); | |
| 138 } | |
| 139 | |
| 140 #if FMT_USE_FCNTL | |
| 141 TEST(scan_test, file) { | |
| 142 fmt::file read_end, write_end; | |
| 143 fmt::file::pipe(read_end, write_end); | |
| 144 | |
| 145 fmt::string_view input = "10 20"; | |
| 146 write_end.write(input.data(), input.size()); | |
| 147 write_end.close(); | |
| 148 | |
| 149 int n1 = 0, n2 = 0; | |
| 150 fmt::buffered_file f = read_end.fdopen("r"); | |
| 151 fmt::scan(f.get(), "{} {}", n1, n2); | |
| 152 EXPECT_EQ(n1, 10); | |
| 153 EXPECT_EQ(n2, 20); | |
| 154 } | |
| 155 | |
| 156 TEST(scan_test, lock) { | |
| 157 fmt::file read_end, write_end; | |
| 158 fmt::file::pipe(read_end, write_end); | |
| 159 | |
| 160 std::thread producer([&]() { | |
| 161 fmt::string_view input = "42 "; | |
| 162 for (int i = 0; i < 1000; ++i) write_end.write(input.data(), input.size()); | |
| 163 write_end.close(); | |
| 164 }); | |
| 165 | |
| 166 std::atomic<int> count(0); | |
| 167 fmt::buffered_file f = read_end.fdopen("r"); | |
| 168 auto fun = [&]() { | |
| 169 int value = 0; | |
| 170 while (fmt::scan(f.get(), "{}", value)) { | |
| 171 if (value != 42) { | |
| 172 read_end.close(); | |
| 173 EXPECT_EQ(value, 42); | |
| 174 break; | |
| 175 } | |
| 176 ++count; | |
| 177 } | |
| 178 }; | |
| 179 std::thread consumer1(fun); | |
| 180 std::thread consumer2(fun); | |
| 181 | |
| 182 producer.join(); | |
| 183 consumer1.join(); | |
| 184 consumer2.join(); | |
| 185 EXPECT_EQ(count, 1000); | |
| 186 | |
| 187 } | |
| 188 #endif // FMT_USE_FCNTL |
