diff options
author | Simon Marchi <simon.marchi@ericsson.com> | 2018-07-26 18:55:02 +0000 |
---|---|---|
committer | Simon Marchi <simon.marchi@ericsson.com> | 2018-07-26 18:55:02 +0000 |
commit | 9980c261df44e62b1a374c58a94c55c76e1e50a7 (patch) | |
tree | fcdbcdb865e01f728dd37d045d168cc2308c2042 /clang/unittests/Basic/VirtualFileSystemTest.cpp | |
parent | ef6c43dc0cb2b05ec9b8500dfb934ac70664d591 (diff) | |
download | llvm-9980c261df44e62b1a374c58a94c55c76e1e50a7.zip llvm-9980c261df44e62b1a374c58a94c55c76e1e50a7.tar.gz llvm-9980c261df44e62b1a374c58a94c55c76e1e50a7.tar.bz2 |
[VirtualFileSystem] InMemoryFileSystem::status: Return a Status with the requested name
Summary:
InMemoryFileSystem::status behaves differently than
RealFileSystem::status. The Name contained in the Status returned by
RealFileSystem::status will be the path as requested by the caller,
whereas InMemoryFileSystem::status returns the normalized path.
For example, when requested the status for "../src/first.h",
RealFileSystem returns a Status with "../src/first.h" as the Name.
InMemoryFileSystem returns "/absolute/path/to/src/first.h".
The reason for this change is that I want to make a unit test in the
clangd testsuite (where we use an InMemoryFileSystem) to reproduce a
bug I get with the clangd program (where a RealFileSystem is used).
This difference in behavior "hides" the bug in the unit test version.
Reviewers: malaperle, ilya-biryukov, bkramer
Subscribers: cfe-commits, ioeric, ilya-biryukov, bkramer, hokein, omtcyfz
Differential Revision: https://reviews.llvm.org/D48903
llvm-svn: 338057
Diffstat (limited to 'clang/unittests/Basic/VirtualFileSystemTest.cpp')
-rw-r--r-- | clang/unittests/Basic/VirtualFileSystemTest.cpp | 59 |
1 files changed, 49 insertions, 10 deletions
diff --git a/clang/unittests/Basic/VirtualFileSystemTest.cpp b/clang/unittests/Basic/VirtualFileSystemTest.cpp index c795be0..a9b39b5 100644 --- a/clang/unittests/Basic/VirtualFileSystemTest.cpp +++ b/clang/unittests/Basic/VirtualFileSystemTest.cpp @@ -13,6 +13,7 @@ #include "llvm/Support/Errc.h" #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" #include "llvm/Support/SourceMgr.h" #include "gtest/gtest.h" #include <map> @@ -151,6 +152,13 @@ public: addEntry(Path, S); } }; + +/// Replace back-slashes by front-slashes. +std::string getPosixPath(std::string S) { + SmallString<128> Result; + llvm::sys::path::native(S, Result, llvm::sys::path::Style::posix); + return Result.str(); +}; } // end anonymous namespace TEST(VirtualFileSystemTest, StatusQueries) { @@ -782,7 +790,9 @@ TEST_F(InMemoryFileSystemTest, DirectoryIteration) { I = FS.dir_begin("/b", EC); ASSERT_FALSE(EC); - ASSERT_EQ("/b/c", I->getName()); + // When on Windows, we end up with "/b\\c" as the name. Convert to Posix + // path for the sake of the comparison. + ASSERT_EQ("/b/c", getPosixPath(I->getName())); I.increment(EC); ASSERT_FALSE(EC); ASSERT_EQ(vfs::directory_iterator(), I); @@ -794,23 +804,19 @@ TEST_F(InMemoryFileSystemTest, WorkingDirectory) { auto Stat = FS.status("/b/c"); ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - ASSERT_EQ("c", Stat->getName()); + ASSERT_EQ("/b/c", Stat->getName()); ASSERT_EQ("/b", *FS.getCurrentWorkingDirectory()); Stat = FS.status("c"); ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" << FS.toString(); - auto ReplaceBackslashes = [](std::string S) { - std::replace(S.begin(), S.end(), '\\', '/'); - return S; - }; NormalizedFS.setCurrentWorkingDirectory("/b/c"); NormalizedFS.setCurrentWorkingDirectory("."); - ASSERT_EQ("/b/c", ReplaceBackslashes( - NormalizedFS.getCurrentWorkingDirectory().get())); + ASSERT_EQ("/b/c", + getPosixPath(NormalizedFS.getCurrentWorkingDirectory().get())); NormalizedFS.setCurrentWorkingDirectory(".."); - ASSERT_EQ("/b", ReplaceBackslashes( - NormalizedFS.getCurrentWorkingDirectory().get())); + ASSERT_EQ("/b", + getPosixPath(NormalizedFS.getCurrentWorkingDirectory().get())); } #if !defined(_WIN32) @@ -919,6 +925,39 @@ TEST_F(InMemoryFileSystemTest, AddDirectoryThenAddChild) { ASSERT_TRUE(Stat->isRegularFile()); } +// Test that the name returned by status() is in the same form as the path that +// was requested (to match the behavior of RealFileSystem). +TEST_F(InMemoryFileSystemTest, StatusName) { + NormalizedFS.addFile("/a/b/c", 0, MemoryBuffer::getMemBuffer("abc"), + /*User=*/None, + /*Group=*/None, sys::fs::file_type::regular_file); + NormalizedFS.setCurrentWorkingDirectory("/a/b"); + + // Access using InMemoryFileSystem::status. + auto Stat = NormalizedFS.status("../b/c"); + ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" + << NormalizedFS.toString(); + ASSERT_TRUE(Stat->isRegularFile()); + ASSERT_EQ("../b/c", Stat->getName()); + + // Access using InMemoryFileAdaptor::status. + auto File = NormalizedFS.openFileForRead("../b/c"); + ASSERT_FALSE(File.getError()) << File.getError() << "\n" + << NormalizedFS.toString(); + Stat = (*File)->status(); + ASSERT_FALSE(Stat.getError()) << Stat.getError() << "\n" + << NormalizedFS.toString(); + ASSERT_TRUE(Stat->isRegularFile()); + ASSERT_EQ("../b/c", Stat->getName()); + + // Access using a directory iterator. + std::error_code EC; + clang::vfs::directory_iterator It = NormalizedFS.dir_begin("../b", EC); + // When on Windows, we end up with "../b\\c" as the name. Convert to Posix + // path for the sake of the comparison. + ASSERT_EQ("../b/c", getPosixPath(It->getName())); +} + // NOTE: in the tests below, we use '//root/' as our root directory, since it is // a legal *absolute* path on Windows as well as *nix. class VFSFromYAMLTest : public ::testing::Test { |