Skip to content

Commit 8783c3c

Browse files
enable fmt_module tests by updating module-test.cc (#4702)
- Update g++ module testing to use g++ version 15 instead of 14. The module support in version 14 isn't very stable and the module testing was not working due to unresolved locale symbols. - Update CI for linux and macos to add verbosity so its consistent with windows. - Refactor test/CMakeLists.txt to enable testing for modules - The tests in `module-test.cc` seem to not have been updated in some time despite changes in the main library. - Wide String versions of several tests appear to be deprecated so have been removed. - Refactored tests related to `fmt::format_args` that now requires lvalue references as opposed to direct values. - Remove the none-working code identified in the `module-test.cc` file while updating.
1 parent 27d0c03 commit 8783c3c

File tree

4 files changed

+46
-114
lines changed

4 files changed

+46
-114
lines changed

.github/workflows/linux.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ jobs:
3737
std: 23
3838
install: sudo apt install g++-13
3939
shared: -DBUILD_SHARED_LIBS=ON
40-
- cxx: g++-14
40+
- cxx: g++-15
4141
build_type: Release
4242
std: 23
43-
install: sudo apt install g++-14
43+
install: sudo apt install g++-15
4444
gen: Ninja
4545
- cxx: clang++-3.6
4646
- cxx: clang++-11
@@ -147,7 +147,7 @@ jobs:
147147
- name: Add repositories for newer GCC
148148
run: |
149149
sudo apt-add-repository ppa:ubuntu-toolchain-r/test
150-
if: ${{ matrix.cxx == 'g++-13' || matrix.cxx == 'g++-14' }}
150+
if: ${{ matrix.cxx == 'g++-13' || matrix.cxx == 'g++-15' }}
151151

152152
- name: Install LLVM-20
153153
run: |
@@ -200,6 +200,6 @@ jobs:
200200
201201
- name: Test
202202
working-directory: ${{runner.workspace}}/build
203-
run: ctest -C ${{matrix.build_type}}
203+
run: ctest -C ${{matrix.build_type}} -V
204204
env:
205205
CTEST_OUTPUT_ON_FAILURE: True

.github/workflows/macos.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@ jobs:
5353
5454
- name: Test
5555
working-directory: ${{runner.workspace}}/build
56-
run: ctest -C ${{matrix.build_type}}
56+
run: ctest -C ${{matrix.build_type}} -V
5757
env:
5858
CTEST_OUTPUT_ON_FAILURE: True

test/CMakeLists.txt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function (add_fmt_test name)
1919
set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wno-weak-vtables)
2020
endif ()
2121
elseif (ADD_FMT_TEST_MODULE)
22-
set(libs test-main)
22+
set(libs test-main fmt-module)
2323
else ()
2424
set(libs test-main fmt)
2525
endif ()
@@ -81,9 +81,7 @@ add_executable(perf-sanity perf-sanity.cc)
8181
target_link_libraries(perf-sanity fmt::fmt)
8282

8383
if (FMT_MODULE)
84-
# Module tests are currently disabled.
85-
# add_fmt_test(module-test MODULE test-main.cc)
86-
# target_link_libraries(module-test fmt-module)
84+
add_fmt_test(module-test MODULE)
8785
endif ()
8886

8987
if (NOT DEFINED MSVC_STATIC_RUNTIME AND MSVC)

test/module-test.cc

Lines changed: 39 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <string>
2626
#include <string_view>
2727
#include <system_error>
28+
#include <gmock/gmock.h>
2829

2930
#if (__has_include(<fcntl.h>) || defined(__APPLE__) || \
3031
defined(__linux__)) && \
@@ -51,6 +52,8 @@ static bool macro_leaked =
5152
#endif
5253

5354
#define FMT_OS_H_ // don't pull in os.h, neither directly nor indirectly
55+
// this define plus the #include <gmock/gmock.h> above
56+
// prevents header inclusion after the import fmt statement
5457
#include "gtest-extra.h"
5558

5659
// an implicitly exported namespace must be visible [module.interface]/2.2
@@ -60,32 +63,6 @@ TEST(module_test, namespace) {
6063
ASSERT_TRUE(true);
6164
}
6265

63-
namespace detail {
64-
bool oops_detail_namespace_is_visible;
65-
}
66-
67-
namespace fmt {
68-
bool namespace_detail_invisible() {
69-
#if defined(FMT_HIDE_MODULE_BUGS) && defined(_MSC_FULL_VER) && \
70-
_MSC_FULL_VER <= 193700000
71-
// bug in msvc up to at least 17.7:
72-
73-
// the namespace is visible even when it is neither
74-
// implicitly nor explicitly exported
75-
return true;
76-
#else
77-
using namespace detail;
78-
// this fails to compile if fmt::detail is visible
79-
return !oops_detail_namespace_is_visible;
80-
#endif
81-
}
82-
} // namespace fmt
83-
84-
// the non-exported namespace 'detail' must be invisible [module.interface]/2
85-
TEST(module_test, detail_namespace) {
86-
EXPECT_TRUE(fmt::namespace_detail_invisible());
87-
}
88-
8966
// macros must not be imported from a *named* module [cpp.import]/5.1
9067
TEST(module_test, macros) {
9168
#if defined(FMT_HIDE_MODULE_BUGS) && defined(_MSC_FULL_VER) && \
@@ -170,7 +147,8 @@ TEST(module_test, format_args) {
170147
auto no_args = fmt::format_args();
171148
EXPECT_FALSE(no_args.get(1));
172149

173-
fmt::basic_format_args args = fmt::make_format_args(42);
150+
int n = 42;
151+
fmt::basic_format_args<fmt::format_context> args = fmt::make_format_args(n);
174152
EXPECT_TRUE(args.max_size() > 0);
175153
auto arg0 = args.get(0);
176154
EXPECT_TRUE(arg0);
@@ -182,41 +160,35 @@ TEST(module_test, format_args) {
182160
TEST(module_test, wformat_args) {
183161
auto no_args = fmt::wformat_args();
184162
EXPECT_FALSE(no_args.get(1));
185-
fmt::basic_format_args args = fmt::make_wformat_args(42);
163+
int n = 42;
164+
fmt::basic_format_args<fmt::wformat_context> args = fmt::make_wformat_args(n);
186165
EXPECT_TRUE(args.get(0));
187166
}
188167

189168
TEST(module_test, dynamic_format_args) {
190169
fmt::dynamic_format_arg_store<fmt::format_context> dyn_store;
191170
dyn_store.push_back(fmt::arg("a42", 42));
192-
fmt::basic_format_args args = dyn_store;
171+
172+
fmt::basic_format_args<fmt::format_context> args = dyn_store;
193173
EXPECT_FALSE(args.get(3));
194174
EXPECT_TRUE(args.get(fmt::string_view("a42")));
195-
196-
fmt::dynamic_format_arg_store<fmt::wformat_context> wdyn_store;
197-
wdyn_store.push_back(fmt::arg(L"a42", 42));
198-
fmt::basic_format_args wargs = wdyn_store;
199-
EXPECT_FALSE(wargs.get(3));
200-
EXPECT_TRUE(wargs.get(fmt::wstring_view(L"a42")));
201175
}
202176

203177
TEST(module_test, vformat) {
204-
EXPECT_EQ("42", fmt::vformat("{}", fmt::make_format_args(42)));
178+
int n = 42;
179+
EXPECT_EQ("42", fmt::vformat("{}", fmt::make_format_args(n)));
205180
EXPECT_EQ(L"42",
206-
fmt::vformat(fmt::wstring_view(L"{}"), fmt::make_wformat_args(42)));
181+
fmt::vformat(fmt::wstring_view(L"{}"), fmt::make_wformat_args(n)));
207182
}
208183

209184
TEST(module_test, vformat_to) {
210-
auto store = fmt::make_format_args(42);
185+
int n = 42;
186+
auto store = fmt::make_format_args(n);
211187
std::string s;
212188
fmt::vformat_to(std::back_inserter(s), "{}", store);
213189
EXPECT_EQ("42", s);
214190

215-
char buffer[4] = {0};
216-
fmt::vformat_to(buffer, "{:}", store);
217-
EXPECT_EQ("42", std::string_view(buffer));
218-
219-
auto wstore = fmt::make_wformat_args(42);
191+
auto wstore = fmt::make_wformat_args(n);
220192
std::wstring w;
221193
fmt::vformat_to(std::back_inserter(w), L"{}", wstore);
222194
EXPECT_EQ(L"42", w);
@@ -227,16 +199,15 @@ TEST(module_test, vformat_to) {
227199
}
228200

229201
TEST(module_test, vformat_to_n) {
230-
auto store = fmt::make_format_args(12345);
202+
int n = 12345;
203+
auto store = fmt::make_format_args(n);
231204
std::string s;
232-
auto result = fmt::vformat_to_n(std::back_inserter(s), 1, "{}", store);
205+
fmt::vformat_to_n(std::back_inserter(s), 1, "{}", store);
233206
char buffer[4] = {0};
234207
fmt::vformat_to_n(buffer, 3, "{:}", store);
235208

236-
auto wstore = fmt::make_wformat_args(12345);
209+
auto wstore = fmt::make_wformat_args(n);
237210
std::wstring w;
238-
auto wresult = fmt::vformat_to_n(std::back_inserter(w), 1,
239-
fmt::wstring_view(L"{}"), wstore);
240211
wchar_t wbuffer[4] = {0};
241212
fmt::vformat_to_n(wbuffer, 3, fmt::wstring_view(L"{:}"), wstore);
242213
}
@@ -249,18 +220,14 @@ std::string as_string(std::wstring_view text) {
249220
TEST(module_test, print) {
250221
EXPECT_WRITE(stdout, fmt::print("{}µ", 42), "42µ");
251222
EXPECT_WRITE(stderr, fmt::print(stderr, "{}µ", 4.2), "4.2µ");
252-
EXPECT_WRITE(stdout, fmt::print(L"{}µ", 42), as_string(L"42µ"));
253-
EXPECT_WRITE(stderr, fmt::print(stderr, L"{}µ", 4.2), as_string(L"4.2µ"));
254223
}
255224

256225
TEST(module_test, vprint) {
257-
EXPECT_WRITE(stdout, fmt::vprint("{:}µ", fmt::make_format_args(42)), "42µ");
258-
EXPECT_WRITE(stderr, fmt::vprint(stderr, "{}", fmt::make_format_args(4.2)),
226+
int n = 42;
227+
double m = 4.2;
228+
EXPECT_WRITE(stdout, fmt::vprint("{:}µ", fmt::make_format_args(n)), "42µ");
229+
EXPECT_WRITE(stderr, fmt::vprint(stderr, "{}", fmt::make_format_args(m)),
259230
"4.2");
260-
EXPECT_WRITE(stdout, fmt::vprint(L"{:}µ", fmt::make_wformat_args(42)),
261-
as_string(L"42µ"));
262-
EXPECT_WRITE(stderr, fmt::vprint(stderr, L"{}", fmt::make_wformat_args(42)),
263-
as_string(L"42"));
264231
}
265232

266233
TEST(module_test, named_args) {
@@ -275,7 +242,8 @@ TEST(module_test, literals) {
275242
}
276243

277244
TEST(module_test, locale) {
278-
auto store = fmt::make_format_args(4.2);
245+
const double m = 4.2;
246+
auto store = fmt::make_format_args(m);
279247
const auto classic = std::locale::classic();
280248
EXPECT_EQ("4.2", fmt::format(classic, "{:L}", 4.2));
281249
EXPECT_EQ("4.2", fmt::vformat(classic, "{:L}", store));
@@ -284,12 +252,9 @@ TEST(module_test, locale) {
284252
EXPECT_EQ("4.2", s);
285253
EXPECT_EQ("4.2", fmt::format("{:L}", 4.2));
286254

287-
auto wstore = fmt::make_wformat_args(4.2);
255+
auto wstore = fmt::make_wformat_args(m);
288256
EXPECT_EQ(L"4.2", fmt::format(classic, L"{:L}", 4.2));
289257
EXPECT_EQ(L"4.2", fmt::vformat(classic, L"{:L}", wstore));
290-
std::wstring w;
291-
fmt::vformat_to(std::back_inserter(w), classic, L"{:L}", wstore);
292-
EXPECT_EQ(L"4.2", w);
293258
EXPECT_EQ(L"4.2", fmt::format(L"{:L}", 4.2));
294259
}
295260

@@ -313,34 +278,17 @@ TEST(module_test, memory_buffer) {
313278
EXPECT_EQ("42", to_string(buffer));
314279
nbuffer.clear();
315280
EXPECT_EQ(0u, to_string(nbuffer).size());
316-
317-
fmt::wmemory_buffer wbuffer;
318-
EXPECT_EQ(0u, to_string(wbuffer).size());
319-
}
320-
321-
TEST(module_test, is_char) {
322-
EXPECT_TRUE(fmt::is_char<char>());
323-
EXPECT_TRUE(fmt::is_char<wchar_t>());
324-
EXPECT_TRUE(fmt::is_char<char8_t>());
325-
EXPECT_TRUE(fmt::is_char<char16_t>());
326-
EXPECT_TRUE(fmt::is_char<char32_t>());
327-
EXPECT_FALSE(fmt::is_char<signed char>());
328281
}
329282

330283
TEST(module_test, ptr) {
331284
uintptr_t answer = 42;
332285
auto p = std::bit_cast<int*>(answer);
333286
EXPECT_EQ("0x2a", fmt::to_string(fmt::ptr(p)));
334-
std::unique_ptr<int> up(p);
335-
EXPECT_EQ("0x2a", fmt::to_string(fmt::ptr(up)));
336-
up.release();
337-
auto sp = std::make_shared<int>(0);
338-
p = sp.get();
339-
EXPECT_EQ(fmt::to_string(fmt::ptr(p)), fmt::to_string(fmt::ptr(sp)));
340287
}
341288

342289
TEST(module_test, errors) {
343-
auto store = fmt::make_format_args(42);
290+
int n = 42;
291+
auto store = fmt::make_format_args(n);
344292
EXPECT_THROW(throw fmt::format_error("oops"), std::exception);
345293
EXPECT_THROW(throw fmt::vsystem_error(0, "{}", store), std::system_error);
346294
EXPECT_THROW(throw fmt::system_error(0, "{}", 42), std::system_error);
@@ -365,8 +313,6 @@ TEST(module_test, error_code) {
365313
fmt::format("{0}", std::error_code(42, std::generic_category())));
366314
EXPECT_EQ("system:42",
367315
fmt::format("{0}", std::error_code(42, fmt::system_category())));
368-
EXPECT_EQ(L"generic:42",
369-
fmt::format(L"{0}", std::error_code(42, std::generic_category())));
370316
}
371317

372318
TEST(module_test, format_int) {
@@ -385,23 +331,19 @@ TEST(module_test, formatter) { EXPECT_TRUE(test_formatter{}.check()); }
385331
TEST(module_test, join) {
386332
int arr[3] = {1, 2, 3};
387333
std::vector<double> vec{1.0, 2.0, 3.0};
388-
std::initializer_list<int> il{1, 2, 3};
389334
auto sep = fmt::string_view(", ");
390335
EXPECT_EQ("1, 2, 3", to_string(fmt::join(arr + 0, arr + 3, sep)));
391336
EXPECT_EQ("1, 2, 3", to_string(fmt::join(arr, sep)));
392337
EXPECT_EQ("1, 2, 3", to_string(fmt::join(vec.begin(), vec.end(), sep)));
393338
EXPECT_EQ("1, 2, 3", to_string(fmt::join(vec, sep)));
394-
EXPECT_EQ("1, 2, 3", to_string(fmt::join(il, sep)));
395339

396340
auto wsep = fmt::wstring_view(L", ");
397341
EXPECT_EQ(L"1, 2, 3", fmt::format(L"{}", fmt::join(arr + 0, arr + 3, wsep)));
398342
EXPECT_EQ(L"1, 2, 3", fmt::format(L"{}", fmt::join(arr, wsep)));
399-
EXPECT_EQ(L"1, 2, 3", fmt::format(L"{}", fmt::join(il, wsep)));
400343
}
401344

402345
TEST(module_test, time) {
403346
auto time_now = std::time(nullptr);
404-
EXPECT_TRUE(fmt::localtime(time_now).tm_year > 120);
405347
EXPECT_TRUE(fmt::gmtime(time_now).tm_year > 120);
406348
auto chrono_now = std::chrono::system_clock::now();
407349
EXPECT_TRUE(fmt::gmtime(chrono_now).tm_year > 120);
@@ -433,42 +375,34 @@ TEST(module_test, weekday) {
433375
TEST(module_test, printf) {
434376
EXPECT_WRITE(stdout, fmt::printf("%f", 42.123456), "42.123456");
435377
EXPECT_WRITE(stdout, fmt::printf("%d", 42), "42");
436-
EXPECT_WRITE(stdout, fmt::printf(L"%f", 42.123456), as_string(L"42.123456"));
437-
EXPECT_WRITE(stdout, fmt::printf(L"%d", 42), as_string(L"42"));
438378
}
439379

440380
TEST(module_test, fprintf) {
441381
EXPECT_WRITE(stderr, fmt::fprintf(stderr, "%d", 42), "42");
442-
EXPECT_WRITE(stderr, fmt::fprintf(stderr, L"%d", 42), as_string(L"42"));
443382
}
444383

445384
TEST(module_test, sprintf) {
446385
EXPECT_EQ("42", fmt::sprintf("%d", 42));
447-
EXPECT_EQ(L"42", fmt::sprintf(L"%d", 42));
448-
}
449-
450-
TEST(module_test, vprintf) {
451-
EXPECT_WRITE(stdout, fmt::vprintf("%d", fmt::make_printf_args(42)), "42");
452-
EXPECT_WRITE(stdout, fmt::vprintf(L"%d", fmt::make_wprintf_args(42)),
453-
as_string(L"42"));
454386
}
455387

456388
TEST(module_test, vfprintf) {
457-
auto args = fmt::make_printf_args(42);
458-
EXPECT_WRITE(stderr, fmt::vfprintf(stderr, "%d", args), "42");
459-
auto wargs = fmt::make_wprintf_args(42);
460-
EXPECT_WRITE(stderr, fmt::vfprintf(stderr, L"%d", wargs), as_string(L"42"));
389+
int n = 42;
390+
auto store = fmt::make_format_args<fmt::printf_context>(n);
391+
auto args = fmt::basic_format_args<fmt::printf_context>(store);
392+
EXPECT_WRITE(stdout, fmt::vfprintf(stdout, fmt::string_view("%d"), args),
393+
"42");
461394
}
462395

463396
TEST(module_test, vsprintf) {
464-
EXPECT_EQ("42", fmt::vsprintf("%d", fmt::make_printf_args(42)));
465-
EXPECT_EQ(L"42", fmt::vsprintf(L"%d", fmt::make_wprintf_args(42)));
397+
int n = 42;
398+
auto store = fmt::make_format_args<fmt::printf_context>(n);
399+
auto args = fmt::basic_format_args<fmt::printf_context>(store);
400+
EXPECT_EQ(fmt::vsprintf(fmt::string_view("%d"), args), "42");
401+
EXPECT_WRITE(stdout, fmt::vfprintf(stdout, fmt::string_view("%d"), args),
402+
"42");
466403
}
467404

468405
TEST(module_test, color) {
469-
auto fg_check = fg(fmt::rgb(255, 200, 30));
470-
auto bg_check = bg(fmt::color::dark_slate_gray) | fmt::emphasis::italic;
471-
auto emphasis_check = fmt::emphasis::underline | fmt::emphasis::bold;
472406
EXPECT_EQ("\x1B[30m42\x1B[0m",
473407
fmt::format(fg(fmt::terminal_color::black), "{}", 42));
474408
EXPECT_EQ(L"\x1B[30m42\x1B[0m",

0 commit comments

Comments
 (0)