|
4 | 4 | #ifndef QUICK_LINT_JS_FILE_MATCHER_H
|
5 | 5 | #define QUICK_LINT_JS_FILE_MATCHER_H
|
6 | 6 |
|
| 7 | +#include <cerrno> |
| 8 | +#include <cstring> |
7 | 9 | #include <gtest/gtest.h>
|
8 | 10 | #include <quick-lint-js/file.h>
|
| 11 | +#include <quick-lint-js/have.h> |
| 12 | + |
| 13 | +#if QLJS_HAVE_STD_FILESYSTEM |
| 14 | +#include <filesystem> |
| 15 | +#endif |
| 16 | + |
| 17 | +#if QLJS_HAVE_SYS_STAT_H |
| 18 | +#include <sys/stat.h> |
| 19 | +#endif |
9 | 20 |
|
10 | 21 | #define EXPECT_SAME_FILE(path_a, path_b) \
|
11 | 22 | EXPECT_PRED_FORMAT2(::quick_lint_js::assert_same_file, path_a, path_b)
|
12 | 23 |
|
13 | 24 | namespace quick_lint_js {
|
14 |
| -template <class String> |
15 |
| -::testing::AssertionResult assert_same_file(const char *lhs_expr, |
16 |
| - const char *rhs_expr, |
17 |
| - String lhs_path, String rhs_path) { |
18 |
| - canonical_path_result lhs_canonical = canonicalize_path(lhs_path); |
19 |
| - EXPECT_TRUE(lhs_canonical.ok()) << std::move(lhs_canonical).error(); |
20 |
| - canonical_path_result rhs_canonical = canonicalize_path(rhs_path); |
21 |
| - EXPECT_TRUE(rhs_canonical.ok()) << std::move(rhs_canonical).error(); |
22 |
| - if (lhs_canonical.path() == rhs_canonical.path()) { |
| 25 | +inline ::testing::AssertionResult assert_same_file(const char* lhs_expr, |
| 26 | + const char* rhs_expr, |
| 27 | + const char* lhs_path, |
| 28 | + const char* rhs_path) { |
| 29 | + bool same; |
| 30 | +#if QLJS_HAVE_STD_FILESYSTEM |
| 31 | + // TODO(strager): std::filesystem::equivalent treats differnt symlinks |
| 32 | + // pointing to the same file as equivalent. This behavior differs from our |
| 33 | + // lstat-based implementation below. |
| 34 | + same = std::filesystem::equivalent(lhs_path, rhs_path); |
| 35 | +#elif QLJS_HAVE_SYS_STAT_H |
| 36 | + { |
| 37 | + struct stat lhs_stat = {}; |
| 38 | + EXPECT_EQ(::lstat(lhs_path, &lhs_stat), 0) << std::strerror(errno); |
| 39 | + |
| 40 | + struct stat rhs_stat = {}; |
| 41 | + EXPECT_EQ(::lstat(rhs_path, &rhs_stat), 0) << std::strerror(errno); |
| 42 | + |
| 43 | + same = lhs_stat.st_dev == rhs_stat.st_dev && |
| 44 | + lhs_stat.st_ino == rhs_stat.st_ino; |
| 45 | + } |
| 46 | +#else |
| 47 | +#error "Unsupported platform" |
| 48 | +#endif |
| 49 | + if (same) { |
23 | 50 | return ::testing::AssertionSuccess();
|
24 | 51 | } else {
|
25 | 52 | return ::testing::AssertionFailure()
|
26 | 53 | << lhs_expr << " (" << lhs_path << ") is not the same file as "
|
27 | 54 | << rhs_expr << " (" << rhs_path << ')';
|
28 | 55 | }
|
29 | 56 | }
|
| 57 | + |
| 58 | +inline ::testing::AssertionResult assert_same_file( |
| 59 | + const char* lhs_expr, const char* rhs_expr, const std::string& lhs_path, |
| 60 | + const std::string& rhs_path) { |
| 61 | + return assert_same_file(lhs_expr, rhs_expr, lhs_path.c_str(), |
| 62 | + rhs_path.c_str()); |
| 63 | +} |
30 | 64 | }
|
31 | 65 |
|
32 | 66 | #endif
|
|
0 commit comments