autoupdate: improve handling of CHECK lines in multi-file input. (#3184)

Write unattached CHECK:STDOUT lines at the end of the complete test
file, not at the end of the first split file.

Also, perform line number remappings for the current file even if we see
a check line for an earlier file first. We used to stop performing
remapping after the first check line that referred to a previous file.

To facilitate this, instead of splitting the check lines up by output
file prior to forming the output, we instead form a single list of check
lines and have the check lines track which file they refer to.
This commit is contained in:
Richard Smith
2023-09-08 20:01:28 +00:00
committed by GitHub
parent 2751f02258
commit 75a7b5c9ee
7 changed files with 205 additions and 124 deletions
+57 -43
View File
@@ -15,25 +15,6 @@ namespace {
using ::testing::Eq;
// Helper to validate file content.
static auto CheckFileContent(llvm::vfs::InMemoryFileSystem& fs,
llvm::StringRef filename,
llvm::StringRef expected_content)
-> ErrorOr<Success> {
auto file = fs.getBufferForFile(filename, /*FileSize=*/-1,
/*RequiresNullTerminator=*/false);
if (file.getError()) {
return ErrorBuilder() << "Missing " << filename;
}
if (file->get()->getBuffer() != expected_content) {
return ErrorBuilder() << "Unexpected file content for " << filename
<< ".\n--- Actual:\n"
<< file->get()->getBuffer() << "\n--- Expected:\n"
<< expected_content << "\n---";
}
return Success();
}
class FileTestBaseTest : public FileTestBase {
public:
using FileTestBase::FileTestBase;
@@ -41,32 +22,34 @@ class FileTestBaseTest : public FileTestBase {
auto Run(const llvm::SmallVector<llvm::StringRef>& test_args,
llvm::vfs::InMemoryFileSystem& fs, llvm::raw_pwrite_stream& stdout,
llvm::raw_pwrite_stream& stderr) -> ErrorOr<bool> override {
if (!test_args.empty()) {
llvm::ListSeparator sep;
stdout << test_args.size() << " args: ";
for (const auto& arg : test_args) {
stdout << sep << "`" << arg << "`";
}
stdout << "\n";
}
llvm::ArrayRef<llvm::StringRef> args = test_args;
auto filename = path().filename().string();
if (filename == "two_files.carbon") {
// Verify the split.
CARBON_RETURN_IF_ERROR(CheckFileContent(
fs, "a.carbon", "aaa\n// CHECK:STDOUT: a.carbon:[[@LINE-1]]: 1\n\n"));
CARBON_RETURN_IF_ERROR(CheckFileContent(
fs, "b.carbon", "bbb\n// CHECK:STDOUT: b.carbon:[[@LINE-1]]: 2\n"));
} else {
// Other files should be copied directly, so aren't as interesting.
if (!fs.exists(filename)) {
return ErrorBuilder() << "Missing file: " << filename;
}
llvm::ListSeparator sep;
stdout << args.size() << " args: ";
for (auto arg : args) {
stdout << sep << "`" << arg << "`";
}
stdout << "\n";
auto filename = path().filename();
if (filename == "args.carbon") {
// 'args.carbon' has custom arguments, so don't do regular argument
// validation for it.
return true;
} else if (filename == "example.carbon") {
}
if (args.empty() || args.front() != "default_args") {
return ErrorBuilder() << "missing `default_args` argument";
}
args = args.drop_front();
for (auto arg : args) {
if (!fs.exists(arg)) {
return ErrorBuilder() << "Missing file: " << arg;
}
}
if (filename == "example.carbon") {
int delta_line = 10;
stdout << "something\n"
<< "\n"
@@ -78,9 +61,40 @@ class FileTestBaseTest : public FileTestBase {
} else if (filename == "fail_example.carbon") {
stderr << "Oops\n";
return false;
} else if (filename == "two_files.carbon") {
// Prints line numbers to validate per-file.
stdout << "a.carbon:1: 1\nb.carbon:1: 2\n";
} else if (filename == "two_files.carbon" ||
filename == "not_split.carbon") {
for (auto arg : args) {
// Describe file contents to stdout to validate splitting.
auto file = fs.getBufferForFile(arg, /*FileSize=*/-1,
/*RequiresNullTerminator=*/false);
if (file.getError()) {
return Error(file.getError().message());
}
llvm::StringRef content = file.get()->getBuffer();
stdout << arg << ":1: starts with \"";
stdout.write_escaped(content.take_front(40));
stdout << "\", length " << content.count('\n') << " lines\n";
}
return true;
} else if (filename == "alternating_files.carbon") {
stdout << "unattached message 1\n"
<< "a.carbon:2: message 2\n"
<< "b.carbon:5: message 3\n"
<< "a.carbon:2: message 4\n"
<< "b.carbon:5: message 5\n"
<< "unattached message 6\n";
stderr << "unattached message 1\n"
<< "a.carbon:2: message 2\n"
<< "b.carbon:5: message 3\n"
<< "a.carbon:2: message 4\n"
<< "b.carbon:5: message 5\n"
<< "unattached message 6\n";
return true;
} else if (filename == "unattached_multi_file.carbon") {
stdout << "unattached message 1\n"
<< "unattached message 2\n";
stderr << "unattached message 3\n"
<< "unattached message 4\n";
return true;
} else {
return ErrorBuilder() << "Unexpected file: " << filename;