| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
- // Exceptions. See /LICENSE for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- #include <gtest/gtest.h>
- #include <fstream>
- #include <string>
- #include "common/set.h"
- #include "llvm/ADT/StringExtras.h"
- #include "re2/re2.h"
- #include "toolchain/diagnostics/diagnostic_kind.h"
- namespace Carbon {
- namespace {
- constexpr DiagnosticKind Diagnostics[] = {
- #define CARBON_DIAGNOSTIC_KIND(Name) DiagnosticKind::Name,
- #include "toolchain/diagnostics/diagnostic_kind.def"
- };
- // Returns true for diagnostics which have no tests. In general, diagnostics
- // should be tested.
- static auto IsUntestedDiagnostic(DiagnosticKind diagnostic_kind) -> bool {
- switch (diagnostic_kind) {
- case DiagnosticKind::TestDiagnostic:
- case DiagnosticKind::TestDiagnosticNote:
- // These exist only for unit tests.
- return true;
- case DiagnosticKind::ErrorReadingFile:
- case DiagnosticKind::ErrorStattingFile:
- case DiagnosticKind::FileTooLarge:
- // These diagnose filesystem issues that are hard to unit test.
- return true;
- case DiagnosticKind::ArrayBoundTooLarge:
- // Int literals are currently limited to i32. Once that's fixed, this
- // should be tested.
- return true;
- case DiagnosticKind::ExternLibraryInImporter:
- case DiagnosticKind::ExternLibraryOnDefinition:
- case DiagnosticKind::HexadecimalEscapeMissingDigits:
- case DiagnosticKind::ImplOfUndefinedInterface:
- case DiagnosticKind::IncompleteTypeInFunctionParam:
- case DiagnosticKind::InvalidDigit:
- case DiagnosticKind::InvalidDigitSeparator:
- case DiagnosticKind::InvalidHorizontalWhitespaceInString:
- case DiagnosticKind::MismatchedIndentInString:
- case DiagnosticKind::ModifierPrivateNotAllowed:
- case DiagnosticKind::MultiLineStringWithDoubleQuotes:
- case DiagnosticKind::NameAmbiguousDueToExtend:
- case DiagnosticKind::TooManyDigits:
- case DiagnosticKind::UnaryOperatorRequiresWhitespace:
- case DiagnosticKind::UnicodeEscapeSurrogate:
- case DiagnosticKind::UnicodeEscapeTooLarge:
- case DiagnosticKind::UnknownBaseSpecifier:
- case DiagnosticKind::UnsupportedCRLineEnding:
- case DiagnosticKind::UnsupportedLFCRLineEnding:
- // TODO: Should look closer at these, but adding tests is a high risk of
- // loss in merge conflicts due to the amount of tests being changed right
- // now.
- return true;
- default:
- return false;
- }
- }
- TEST(EmittedDiagnostics, Verify) {
- std::ifstream manifest_in("toolchain/diagnostics/all_testdata.txt");
- ASSERT_TRUE(manifest_in.good());
- RE2 diagnostic_re(R"(\w\((\w+)\): )");
- ASSERT_TRUE(diagnostic_re.ok()) << diagnostic_re.error();
- Set<std::string> emitted_diagnostics;
- std::string test_filename;
- while (std::getline(manifest_in, test_filename)) {
- std::ifstream test_in(test_filename);
- ASSERT_TRUE(test_in.good());
- std::string line;
- while (std::getline(test_in, line)) {
- std::string diagnostic;
- if (RE2::PartialMatch(line, diagnostic_re, &diagnostic)) {
- emitted_diagnostics.Insert(diagnostic);
- }
- }
- }
- llvm::SmallVector<llvm::StringRef> missing_diagnostics;
- for (auto diagnostic_kind : Diagnostics) {
- if (IsUntestedDiagnostic(diagnostic_kind)) {
- EXPECT_FALSE(emitted_diagnostics.Erase(diagnostic_kind.name()))
- << diagnostic_kind
- << " was previously untested, and is now tested. That's good, but "
- "please remove it from IsUntestedDiagnostic.";
- continue;
- }
- if (!emitted_diagnostics.Erase(diagnostic_kind.name())) {
- missing_diagnostics.push_back(diagnostic_kind.name());
- }
- }
- constexpr llvm::StringLiteral Bullet = "\n - ";
- std::sort(missing_diagnostics.begin(), missing_diagnostics.end());
- EXPECT_TRUE(missing_diagnostics.empty())
- << "Some diagnostics have no tests:" << Bullet
- << llvm::join(missing_diagnostics, Bullet);
- llvm::SmallVector<std::string> unexpected_matches;
- emitted_diagnostics.ForEach(
- [&](const std::string& match) { unexpected_matches.push_back(match); });
- std::sort(unexpected_matches.begin(), unexpected_matches.end());
- EXPECT_TRUE(unexpected_matches.empty())
- << "Matched things that don't appear to be diagnostics:" << Bullet
- << llvm::join(unexpected_matches, Bullet);
- }
- } // namespace
- } // namespace Carbon
|