[llvm] f1ad192 - [FileCheck] Strengthen error checks in unit tests

Thomas Preud'homme via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 23 03:32:00 PST 2020


Author: Thomas Preud'homme
Date: 2020-01-23T11:31:53Z
New Revision: f1ad192915f64e3eeedfb01aa1073e81bff4e1a1

URL: https://github.com/llvm/llvm-project/commit/f1ad192915f64e3eeedfb01aa1073e81bff4e1a1
DIFF: https://github.com/llvm/llvm-project/commit/f1ad192915f64e3eeedfb01aa1073e81bff4e1a1.diff

LOG: [FileCheck] Strengthen error checks in unit tests

Summary:
This commit adds error checking beyond UndefVarError and fix a number of
Error/Expected related idioms:
- use (EXPECT|ASSERT)_THAT_(ERROR|EXPECTED) instead of errorToBool or
  boolean operator
- ASSERT when a further check require the check to be successful to give
  a correct result

Reviewers: jhenderson, jdenny, probinson, grimar, arichardson, rnk

Reviewed By: jhenderson

Subscribers: llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D72914

Added: 
    

Modified: 
    llvm/unittests/Support/FileCheckTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/unittests/Support/FileCheckTest.cpp b/llvm/unittests/Support/FileCheckTest.cpp
index 9be02c1f377f..ebe2362f5894 100644
--- a/llvm/unittests/Support/FileCheckTest.cpp
+++ b/llvm/unittests/Support/FileCheckTest.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/Support/FileCheck.h"
 #include "../lib/Support/FileCheckImpl.h"
+#include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
 #include <unordered_set>
 
@@ -21,13 +22,13 @@ TEST_F(FileCheckTest, Literal) {
   // Eval returns the literal's value.
   ExpressionLiteral Ten(10);
   Expected<uint64_t> Value = Ten.eval();
-  ASSERT_TRUE(bool(Value));
+  ASSERT_THAT_EXPECTED(Value, Succeeded());
   EXPECT_EQ(10U, *Value);
 
   // Max value can be correctly represented.
   ExpressionLiteral Max(std::numeric_limits<uint64_t>::max());
   Value = Max.eval();
-  ASSERT_TRUE(bool(Value));
+  ASSERT_THAT_EXPECTED(Value, Succeeded());
   EXPECT_EQ(std::numeric_limits<uint64_t>::max(), *Value);
 }
 
@@ -45,18 +46,15 @@ static std::string toString(const std::unordered_set<std::string> &Set) {
 static void
 expectUndefErrors(std::unordered_set<std::string> ExpectedUndefVarNames,
                   Error Err) {
-  handleAllErrors(std::move(Err), [&](const UndefVarError &E) {
-    ExpectedUndefVarNames.erase(E.getVarName());
-  });
+  EXPECT_THAT_ERROR(
+      handleErrors(std::move(Err),
+                   [&](const UndefVarError &E) {
+                     EXPECT_EQ(ExpectedUndefVarNames.erase(E.getVarName()), 1U);
+                   }),
+      Succeeded());
   EXPECT_TRUE(ExpectedUndefVarNames.empty()) << toString(ExpectedUndefVarNames);
 }
 
-// Return whether Err contains any UndefVarError whose associated name is not
-// ExpectedUndefVarName.
-static void expectUndefError(const Twine &ExpectedUndefVarName, Error Err) {
-  expectUndefErrors({ExpectedUndefVarName.str()}, std::move(Err));
-}
-
 uint64_t doAdd(uint64_t OpL, uint64_t OpR) { return OpL + OpR; }
 
 TEST_F(FileCheckTest, NumericVariable) {
@@ -67,17 +65,16 @@ TEST_F(FileCheckTest, NumericVariable) {
   NumericVariableUse FooVarUse("FOO", &FooVar);
   EXPECT_FALSE(FooVar.getValue());
   Expected<uint64_t> EvalResult = FooVarUse.eval();
-  ASSERT_FALSE(EvalResult);
-  expectUndefError("FOO", EvalResult.takeError());
+  expectUndefErrors({"FOO"}, EvalResult.takeError());
 
   FooVar.setValue(42);
 
   // Defined variable: getValue and eval return value set.
   Optional<uint64_t> Value = FooVar.getValue();
-  ASSERT_TRUE(bool(Value));
+  ASSERT_TRUE(Value);
   EXPECT_EQ(42U, *Value);
   EvalResult = FooVarUse.eval();
-  ASSERT_TRUE(bool(EvalResult));
+  ASSERT_THAT_EXPECTED(EvalResult, Succeeded());
   EXPECT_EQ(42U, *EvalResult);
 
   // Clearing variable: getValue and eval fail. Error returned by eval holds
@@ -85,8 +82,7 @@ TEST_F(FileCheckTest, NumericVariable) {
   FooVar.clearValue();
   EXPECT_FALSE(FooVar.getValue());
   EvalResult = FooVarUse.eval();
-  ASSERT_FALSE(EvalResult);
-  expectUndefError("FOO", EvalResult.takeError());
+  expectUndefErrors({"FOO"}, EvalResult.takeError());
 }
 
 TEST_F(FileCheckTest, Binop) {
@@ -102,21 +98,19 @@ TEST_F(FileCheckTest, Binop) {
 
   // Defined variable: eval returns right value.
   Expected<uint64_t> Value = Binop.eval();
-  ASSERT_TRUE(bool(Value));
+  ASSERT_THAT_EXPECTED(Value, Succeeded());
   EXPECT_EQ(60U, *Value);
 
   // 1 undefined variable: eval fails, error contains name of undefined
   // variable.
   FooVar.clearValue();
   Value = Binop.eval();
-  ASSERT_FALSE(Value);
-  expectUndefError("FOO", Value.takeError());
+  expectUndefErrors({"FOO"}, Value.takeError());
 
   // 2 undefined variables: eval fails, error contains names of all undefined
   // variables.
   BarVar.clearValue();
   Value = Binop.eval();
-  ASSERT_FALSE(Value);
   expectUndefErrors({"FOO", "BAR"}, Value.takeError());
 }
 
@@ -140,75 +134,97 @@ static StringRef bufferize(SourceMgr &SM, StringRef Str) {
   return StrBufferRef;
 }
 
+template <typename ErrorT>
+static void expectError(StringRef ExpectedMsg, Error Err) {
+  bool ErrorHandled = false;
+  EXPECT_THAT_ERROR(handleErrors(std::move(Err),
+                                 [&](const ErrorT &E) {
+                                   EXPECT_NE(
+                                       E.message().find(ExpectedMsg.str()),
+                                       std::string::npos);
+                                   ErrorHandled = true;
+                                 }),
+                    Succeeded());
+  EXPECT_TRUE(ErrorHandled);
+}
+
+static void expectDiagnosticError(StringRef ExpectedMsg, Error Err) {
+  expectError<ErrorDiagnostic>(ExpectedMsg, std::move(Err));
+}
+
 TEST_F(FileCheckTest, ParseVar) {
   SourceMgr SM;
   StringRef OrigVarName = bufferize(SM, "GoodVar42");
   StringRef VarName = OrigVarName;
   Expected<Pattern::VariableProperties> ParsedVarResult =
       Pattern::parseVariable(VarName, SM);
-  ASSERT_TRUE(bool(ParsedVarResult));
+  ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded());
   EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
   EXPECT_TRUE(VarName.empty());
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
 
   VarName = OrigVarName = bufferize(SM, "$GoodGlobalVar");
   ParsedVarResult = Pattern::parseVariable(VarName, SM);
-  ASSERT_TRUE(bool(ParsedVarResult));
+  ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded());
   EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
   EXPECT_TRUE(VarName.empty());
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
 
   VarName = OrigVarName = bufferize(SM, "@GoodPseudoVar");
   ParsedVarResult = Pattern::parseVariable(VarName, SM);
-  ASSERT_TRUE(bool(ParsedVarResult));
+  ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded());
   EXPECT_EQ(ParsedVarResult->Name, OrigVarName);
   EXPECT_TRUE(VarName.empty());
   EXPECT_TRUE(ParsedVarResult->IsPseudo);
 
   VarName = bufferize(SM, "42BadVar");
   ParsedVarResult = Pattern::parseVariable(VarName, SM);
-  EXPECT_TRUE(errorToBool(ParsedVarResult.takeError()));
+  expectDiagnosticError("invalid variable name", ParsedVarResult.takeError());
 
   VarName = bufferize(SM, "$@");
   ParsedVarResult = Pattern::parseVariable(VarName, SM);
-  EXPECT_TRUE(errorToBool(ParsedVarResult.takeError()));
+  expectDiagnosticError("invalid variable name", ParsedVarResult.takeError());
 
   VarName = OrigVarName = bufferize(SM, "B at dVar");
   ParsedVarResult = Pattern::parseVariable(VarName, SM);
-  ASSERT_TRUE(bool(ParsedVarResult));
+  ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded());
   EXPECT_EQ(VarName, OrigVarName.substr(1));
   EXPECT_EQ(ParsedVarResult->Name, "B");
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
 
   VarName = OrigVarName = bufferize(SM, "B$dVar");
   ParsedVarResult = Pattern::parseVariable(VarName, SM);
-  ASSERT_TRUE(bool(ParsedVarResult));
+  ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded());
   EXPECT_EQ(VarName, OrigVarName.substr(1));
   EXPECT_EQ(ParsedVarResult->Name, "B");
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
 
   VarName = bufferize(SM, "BadVar+");
   ParsedVarResult = Pattern::parseVariable(VarName, SM);
-  ASSERT_TRUE(bool(ParsedVarResult));
+  ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded());
   EXPECT_EQ(VarName, "+");
   EXPECT_EQ(ParsedVarResult->Name, "BadVar");
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
 
   VarName = bufferize(SM, "BadVar-");
   ParsedVarResult = Pattern::parseVariable(VarName, SM);
-  ASSERT_TRUE(bool(ParsedVarResult));
+  ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded());
   EXPECT_EQ(VarName, "-");
   EXPECT_EQ(ParsedVarResult->Name, "BadVar");
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
 
   VarName = bufferize(SM, "BadVar:");
   ParsedVarResult = Pattern::parseVariable(VarName, SM);
-  ASSERT_TRUE(bool(ParsedVarResult));
+  ASSERT_THAT_EXPECTED(ParsedVarResult, Succeeded());
   EXPECT_EQ(VarName, ":");
   EXPECT_EQ(ParsedVarResult->Name, "BadVar");
   EXPECT_FALSE(ParsedVarResult->IsPseudo);
 }
 
+static void expectNotFoundError(Error Err) {
+  expectError<NotFoundError>("String not found in input", std::move(Err));
+}
+
 class PatternTester {
 private:
   size_t LineNumber = 1;
@@ -224,8 +240,8 @@ class PatternTester {
     GlobalDefines.emplace_back(std::string("BAR=BAZ"));
     // An ASSERT_FALSE would make more sense but cannot be used in a
     // constructor.
-    EXPECT_FALSE(
-        errorToBool(Context.defineCmdlineVariables(GlobalDefines, SM)));
+    EXPECT_THAT_ERROR(Context.defineCmdlineVariables(GlobalDefines, SM),
+                      Succeeded());
     Context.createLineVariable();
     // Call parsePattern to have @LINE defined.
     P.parsePattern("N/A", "CHECK", SM, Req);
@@ -241,24 +257,24 @@ class PatternTester {
 
   size_t getLineNumber() const { return LineNumber; }
 
-  bool parseSubstExpect(StringRef Expr, bool IsLegacyLineExpr = false) {
+  Expected<std::unique_ptr<ExpressionAST>>
+  parseSubst(StringRef Expr, bool IsLegacyLineExpr = false) {
     StringRef ExprBufferRef = bufferize(SM, Expr);
     Optional<NumericVariable *> DefinedNumericVariable;
-    return errorToBool(P.parseNumericSubstitutionBlock(
-                            ExprBufferRef, DefinedNumericVariable,
-                            IsLegacyLineExpr, LineNumber, &Context, SM)
-                           .takeError());
+    return P.parseNumericSubstitutionBlock(
+        ExprBufferRef, DefinedNumericVariable, IsLegacyLineExpr, LineNumber,
+        &Context, SM);
   }
 
-  bool parsePatternExpect(StringRef Pattern) {
+  bool parsePattern(StringRef Pattern) {
     StringRef PatBufferRef = bufferize(SM, Pattern);
     return P.parsePattern(PatBufferRef, "CHECK", SM, Req);
   }
 
-  bool matchExpect(StringRef Buffer) {
+  Expected<size_t> match(StringRef Buffer) {
     StringRef BufferRef = bufferize(SM, Buffer);
     size_t MatchLen;
-    return errorToBool(P.match(BufferRef, MatchLen, SM).takeError());
+    return P.match(BufferRef, MatchLen, SM);
   }
 };
 
@@ -267,166 +283,181 @@ TEST_F(FileCheckTest, ParseNumericSubstitutionBlock) {
 
   // Variable definition.
 
-  // Invalid variable name.
-  EXPECT_TRUE(Tester.parseSubstExpect("%VAR:"));
+  expectDiagnosticError("invalid variable name",
+                        Tester.parseSubst("%VAR:").takeError());
 
-  // Invalid definition of pseudo variable.
-  EXPECT_TRUE(Tester.parseSubstExpect("@LINE:"));
+  expectDiagnosticError("definition of pseudo numeric variable unsupported",
+                        Tester.parseSubst("@LINE:").takeError());
 
-  // Conflict with pattern variable.
-  EXPECT_TRUE(Tester.parseSubstExpect("BAR:"));
+  expectDiagnosticError("string variable with name 'BAR' already exists",
+                        Tester.parseSubst("BAR:").takeError());
 
-  // Garbage after name of variable being defined.
-  EXPECT_TRUE(Tester.parseSubstExpect("VAR GARBAGE:"));
+  expectDiagnosticError("unexpected characters after numeric variable name",
+                        Tester.parseSubst("VAR GARBAGE:").takeError());
 
-  // Acceptable variable definition.
-  EXPECT_FALSE(Tester.parseSubstExpect("VAR1:"));
-  EXPECT_FALSE(Tester.parseSubstExpect("  VAR2:"));
-  EXPECT_FALSE(Tester.parseSubstExpect("VAR3  :"));
-  EXPECT_FALSE(Tester.parseSubstExpect("VAR3:  "));
-  EXPECT_FALSE(Tester.parseSubstExpect("FOOBAR: FOO+1"));
+  EXPECT_THAT_EXPECTED(Tester.parseSubst("VAR1:"), Succeeded());
+  EXPECT_THAT_EXPECTED(Tester.parseSubst("  VAR2:"), Succeeded());
+  EXPECT_THAT_EXPECTED(Tester.parseSubst("VAR3  :"), Succeeded());
+  EXPECT_THAT_EXPECTED(Tester.parseSubst("VAR3:  "), Succeeded());
+  EXPECT_THAT_EXPECTED(Tester.parseSubst("FOOBAR: FOO+1"), Succeeded());
 
   // Numeric expression.
 
   // Invalid variable name.
-  EXPECT_TRUE(Tester.parseSubstExpect("%VAR"));
-
-  // Invalid pseudo variable.
-  EXPECT_TRUE(Tester.parseSubstExpect("@FOO"));
-
-  // Invalid use of variable defined on the same line. Use parsePatternExpect
-  // for the variable to be recorded in GlobalNumericVariableTable and thus
-  // appear defined to parseNumericVariableUse. Note that the same pattern
-  // object is used for the parsePatternExpect and parseSubstExpect since no
-  // initNextPattern is called, thus appearing as being on the same line from
-  // the pattern's point of view.
-  ASSERT_FALSE(Tester.parsePatternExpect("[[#SAME_LINE_VAR:]]"));
-  EXPECT_TRUE(Tester.parseSubstExpect("SAME_LINE_VAR"));
+  expectDiagnosticError("invalid operand format '%VAR'",
+                        Tester.parseSubst("%VAR").takeError());
+
+  expectDiagnosticError("invalid pseudo numeric variable '@FOO'",
+                        Tester.parseSubst("@FOO").takeError());
+
+  // parsePattern() is used here instead of parseSubst() for the variable to be
+  // recorded in GlobalNumericVariableTable and thus appear defined to
+  // parseNumericVariableUse(). Note that the same pattern object is used for
+  // the parsePattern() and parseSubst() since no initNextPattern() is called,
+  // thus appearing as being on the same line from the pattern's point of view.
+  ASSERT_FALSE(Tester.parsePattern("[[#SAME_LINE_VAR:]]"));
+  expectDiagnosticError("numeric variable 'SAME_LINE_VAR' defined earlier in "
+                        "the same CHECK directive",
+                        Tester.parseSubst("SAME_LINE_VAR").takeError());
 
   // Invalid use of variable defined on the same line from an expression not
   // using any variable defined on the same line.
-  ASSERT_FALSE(Tester.parsePatternExpect("[[#SAME_LINE_EXPR_VAR:@LINE+1]]"));
-  EXPECT_TRUE(Tester.parseSubstExpect("SAME_LINE_EXPR_VAR"));
+  ASSERT_FALSE(Tester.parsePattern("[[#SAME_LINE_EXPR_VAR:@LINE+1]]"));
+  expectDiagnosticError("numeric variable 'SAME_LINE_EXPR_VAR' defined earlier "
+                        "in the same CHECK directive",
+                        Tester.parseSubst("SAME_LINE_EXPR_VAR").takeError());
 
   // Valid use of undefined variable which creates the variable and record it
   // in GlobalNumericVariableTable.
-  ASSERT_FALSE(Tester.parseSubstExpect("UNDEF"));
-  EXPECT_TRUE(Tester.parsePatternExpect("[[UNDEF:.*]]"));
+  ASSERT_THAT_EXPECTED(Tester.parseSubst("UNDEF"), Succeeded());
+  EXPECT_TRUE(Tester.parsePattern("[[UNDEF:.*]]"));
 
   // Invalid literal.
-  EXPECT_TRUE(Tester.parseSubstExpect("42U"));
+  expectDiagnosticError("unsupported operation 'U'",
+                        Tester.parseSubst("42U").takeError());
 
   // Valid empty expression.
-  EXPECT_FALSE(Tester.parseSubstExpect(""));
+  EXPECT_THAT_EXPECTED(Tester.parseSubst(""), Succeeded());
 
   // Valid single operand expression.
-  EXPECT_FALSE(Tester.parseSubstExpect("FOO"));
+  EXPECT_THAT_EXPECTED(Tester.parseSubst("FOO"), Succeeded());
 
   // Valid expression with 2 or more operands.
-  EXPECT_FALSE(Tester.parseSubstExpect("FOO+3"));
-  EXPECT_FALSE(Tester.parseSubstExpect("FOO-3+FOO"));
+  EXPECT_THAT_EXPECTED(Tester.parseSubst("FOO+3"), Succeeded());
+  EXPECT_THAT_EXPECTED(Tester.parseSubst("FOO-3+FOO"), Succeeded());
 
-  // Unsupported operator.
-  EXPECT_TRUE(Tester.parseSubstExpect("@LINE/2"));
+  expectDiagnosticError("unsupported operation '/'",
+                        Tester.parseSubst("@LINE/2").takeError());
 
-  // Missing RHS operand.
-  EXPECT_TRUE(Tester.parseSubstExpect("@LINE+"));
+  expectDiagnosticError("missing operand in expression",
+                        Tester.parseSubst("@LINE+").takeError());
 
   // Errors in RHS operand are bubbled up by parseBinop() to
-  // parseNumericSubstitutionBlock.
-  EXPECT_TRUE(Tester.parseSubstExpect("@LINE+%VAR"));
+  // parseNumericSubstitutionBlock().
+  expectDiagnosticError("invalid operand format '%VAR'",
+                        Tester.parseSubst("@LINE+%VAR").takeError());
 
   // Invalid legacy @LINE expression with non literal rhs.
-  EXPECT_TRUE(Tester.parseSubstExpect("@LINE+ at LINE", /*IsLegacyNumExpr=*/true));
+  expectDiagnosticError(
+      "invalid operand format '@LINE'",
+      Tester.parseSubst("@LINE+ at LINE", /*IsLegacyNumExpr=*/true).takeError());
 
   // Invalid legacy @LINE expression made of a single literal.
-  EXPECT_TRUE(Tester.parseSubstExpect("2", /*IsLegacyNumExpr=*/true));
+  expectDiagnosticError(
+      "invalid variable name",
+      Tester.parseSubst("2", /*IsLegacyNumExpr=*/true).takeError());
 
   // Valid legacy @LINE expression.
-  EXPECT_FALSE(Tester.parseSubstExpect("@LINE+2", /*IsLegacyNumExpr=*/true));
+  EXPECT_THAT_EXPECTED(Tester.parseSubst("@LINE+2", /*IsLegacyNumExpr=*/true),
+                       Succeeded());
 
   // Invalid legacy @LINE expression with more than 2 operands.
-  EXPECT_TRUE(
-      Tester.parseSubstExpect("@LINE+2+ at LINE", /*IsLegacyNumExpr=*/true));
-  EXPECT_TRUE(Tester.parseSubstExpect("@LINE+2+2", /*IsLegacyNumExpr=*/true));
+  expectDiagnosticError(
+      "unexpected characters at end of expression '+ at LINE'",
+      Tester.parseSubst("@LINE+2+ at LINE", /*IsLegacyNumExpr=*/true).takeError());
+  expectDiagnosticError(
+      "unexpected characters at end of expression '+2'",
+      Tester.parseSubst("@LINE+2+2", /*IsLegacyNumExpr=*/true).takeError());
 }
 
 TEST_F(FileCheckTest, ParsePattern) {
   PatternTester Tester;
 
   // Invalid space in string substitution.
-  EXPECT_TRUE(Tester.parsePatternExpect("[[ BAR]]"));
+  EXPECT_TRUE(Tester.parsePattern("[[ BAR]]"));
 
   // Invalid variable name in string substitution.
-  EXPECT_TRUE(Tester.parsePatternExpect("[[42INVALID]]"));
+  EXPECT_TRUE(Tester.parsePattern("[[42INVALID]]"));
 
   // Invalid string variable definition.
-  EXPECT_TRUE(Tester.parsePatternExpect("[[@PAT:]]"));
-  EXPECT_TRUE(Tester.parsePatternExpect("[[PAT+2:]]"));
+  EXPECT_TRUE(Tester.parsePattern("[[@PAT:]]"));
+  EXPECT_TRUE(Tester.parsePattern("[[PAT+2:]]"));
 
   // Collision with numeric variable.
-  EXPECT_TRUE(Tester.parsePatternExpect("[[FOO:]]"));
+  EXPECT_TRUE(Tester.parsePattern("[[FOO:]]"));
 
   // Valid use of string variable.
-  EXPECT_FALSE(Tester.parsePatternExpect("[[BAR]]"));
+  EXPECT_FALSE(Tester.parsePattern("[[BAR]]"));
 
   // Valid string variable definition.
-  EXPECT_FALSE(Tester.parsePatternExpect("[[PAT:[0-9]+]]"));
+  EXPECT_FALSE(Tester.parsePattern("[[PAT:[0-9]+]]"));
 
   // Invalid numeric substitution.
-  EXPECT_TRUE(Tester.parsePatternExpect("[[#42INVALID]]"));
+  EXPECT_TRUE(Tester.parsePattern("[[#42INVALID]]"));
 
   // Valid numeric substitution.
-  EXPECT_FALSE(Tester.parsePatternExpect("[[#FOO]]"));
+  EXPECT_FALSE(Tester.parsePattern("[[#FOO]]"));
 }
 
 TEST_F(FileCheckTest, Match) {
   PatternTester Tester;
 
   // Check matching an empty expression only matches a number.
-  Tester.parsePatternExpect("[[#]]");
-  EXPECT_TRUE(Tester.matchExpect("FAIL"));
-  EXPECT_FALSE(Tester.matchExpect("18"));
+  ASSERT_FALSE(Tester.parsePattern("[[#]]"));
+  expectNotFoundError(Tester.match("FAIL").takeError());
+  EXPECT_THAT_EXPECTED(Tester.match("18"), Succeeded());
 
   // Check matching a definition only matches a number.
   Tester.initNextPattern();
-  Tester.parsePatternExpect("[[#NUMVAR:]]");
-  EXPECT_TRUE(Tester.matchExpect("FAIL"));
-  EXPECT_TRUE(Tester.matchExpect(""));
-  EXPECT_FALSE(Tester.matchExpect("18"));
+  ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR:]]"));
+  expectNotFoundError(Tester.match("FAIL").takeError());
+  expectNotFoundError(Tester.match("").takeError());
+  EXPECT_THAT_EXPECTED(Tester.match("18"), Succeeded());
 
   // Check matching an undefined variable returns a NotFound error.
   Tester.initNextPattern();
-  ASSERT_FALSE(Tester.parsePatternExpect("100"));
-  EXPECT_TRUE(Tester.matchExpect("101"));
+  ASSERT_FALSE(Tester.parsePattern("100"));
+  expectNotFoundError(Tester.match("101").takeError());
 
   // Check matching the defined variable matches the correct number only.
   Tester.initNextPattern();
-  ASSERT_FALSE(Tester.parsePatternExpect("[[#NUMVAR]]"));
-  EXPECT_FALSE(Tester.matchExpect("18"));
+  ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR]]"));
+  EXPECT_THAT_EXPECTED(Tester.match("18"), Succeeded());
 
   // Check matching several substitutions does not match them independently.
   Tester.initNextPattern();
-  Tester.parsePatternExpect("[[#NUMVAR]] [[#NUMVAR+2]]");
-  EXPECT_TRUE(Tester.matchExpect("19 21"));
-  EXPECT_TRUE(Tester.matchExpect("18 21"));
-  EXPECT_FALSE(Tester.matchExpect("18 20"));
+  ASSERT_FALSE(Tester.parsePattern("[[#NUMVAR]] [[#NUMVAR+2]]"));
+  expectNotFoundError(Tester.match("19 21").takeError());
+  expectNotFoundError(Tester.match("18 21").takeError());
+  EXPECT_THAT_EXPECTED(Tester.match("18 20"), Succeeded());
 
   // Check matching a numeric expression using @LINE after match failure uses
   // the correct value for @LINE.
   Tester.initNextPattern();
-  EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
+  ASSERT_FALSE(Tester.parsePattern("[[#@LINE]]"));
   // Ok, @LINE matches the current line number.
-  EXPECT_FALSE(Tester.matchExpect(std::to_string(Tester.getLineNumber())));
+  EXPECT_THAT_EXPECTED(Tester.match(std::to_string(Tester.getLineNumber())),
+                       Succeeded());
   Tester.initNextPattern();
   // Match with substitution failure.
-  EXPECT_FALSE(Tester.parsePatternExpect("[[#UNKNOWN]]"));
-  EXPECT_TRUE(Tester.matchExpect("FOO"));
+  ASSERT_FALSE(Tester.parsePattern("[[#UNKNOWN]]"));
+  expectUndefErrors({"UNKNOWN"}, Tester.match("FOO").takeError());
   Tester.initNextPattern();
   // Check that @LINE matches the later (given the calls to initNextPattern())
   // line number.
-  EXPECT_FALSE(Tester.parsePatternExpect("[[#@LINE]]"));
-  EXPECT_FALSE(Tester.matchExpect(std::to_string(Tester.getLineNumber())));
+  EXPECT_FALSE(Tester.parsePattern("[[#@LINE]]"));
+  EXPECT_THAT_EXPECTED(Tester.match(std::to_string(Tester.getLineNumber())),
+                       Succeeded());
 }
 
 TEST_F(FileCheckTest, Substitution) {
@@ -434,14 +465,14 @@ TEST_F(FileCheckTest, Substitution) {
   FileCheckPatternContext Context;
   std::vector<std::string> GlobalDefines;
   GlobalDefines.emplace_back(std::string("FOO=BAR"));
-  EXPECT_FALSE(errorToBool(Context.defineCmdlineVariables(GlobalDefines, SM)));
+  EXPECT_THAT_ERROR(Context.defineCmdlineVariables(GlobalDefines, SM),
+                    Succeeded());
 
   // Substitution of an undefined string variable fails and error holds that
   // variable's name.
   StringSubstitution StringSubstitution(&Context, "VAR404", 42);
   Expected<std::string> SubstValue = StringSubstitution.getResult();
-  ASSERT_FALSE(bool(SubstValue));
-  expectUndefError("VAR404", SubstValue.takeError());
+  expectUndefErrors({"VAR404"}, SubstValue.takeError());
 
   // Numeric substitution blocks constituted of defined numeric variables are
   // substituted for the variable's value.
@@ -451,21 +482,20 @@ TEST_F(FileCheckTest, Substitution) {
   NumericSubstitution SubstitutionN(&Context, "N", std::move(NVarUse),
                                     /*InsertIdx=*/30);
   SubstValue = SubstitutionN.getResult();
-  ASSERT_TRUE(bool(SubstValue));
+  ASSERT_THAT_EXPECTED(SubstValue, Succeeded());
   EXPECT_EQ("10", *SubstValue);
 
   // Substitution of an undefined numeric variable fails, error holds name of
   // undefined variable.
   NVar.clearValue();
   SubstValue = SubstitutionN.getResult();
-  ASSERT_FALSE(bool(SubstValue));
-  expectUndefError("N", SubstValue.takeError());
+  expectUndefErrors({"N"}, SubstValue.takeError());
 
   // Substitution of a defined string variable returns the right value.
   Pattern P(Check::CheckPlain, &Context, 1);
   StringSubstitution = llvm::StringSubstitution(&Context, "FOO", 42);
   SubstValue = StringSubstitution.getResult();
-  ASSERT_TRUE(bool(SubstValue));
+  ASSERT_THAT_EXPECTED(SubstValue, Succeeded());
   EXPECT_EQ("BAR", *SubstValue);
 }
 
@@ -475,47 +505,56 @@ TEST_F(FileCheckTest, FileCheckContext) {
   SourceMgr SM;
 
   // No definition.
-  EXPECT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  EXPECT_THAT_ERROR(Cxt.defineCmdlineVariables(GlobalDefines, SM), Succeeded());
 
   // Missing equal sign.
   GlobalDefines.emplace_back(std::string("LocalVar"));
-  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  expectDiagnosticError("missing equal sign in global definition",
+                        Cxt.defineCmdlineVariables(GlobalDefines, SM));
   GlobalDefines.clear();
   GlobalDefines.emplace_back(std::string("#LocalNumVar"));
-  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  expectDiagnosticError("missing equal sign in global definition",
+                        Cxt.defineCmdlineVariables(GlobalDefines, SM));
 
   // Empty variable name.
   GlobalDefines.clear();
   GlobalDefines.emplace_back(std::string("=18"));
-  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  expectDiagnosticError("empty variable name",
+                        Cxt.defineCmdlineVariables(GlobalDefines, SM));
   GlobalDefines.clear();
   GlobalDefines.emplace_back(std::string("#=18"));
-  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  expectDiagnosticError("empty variable name",
+                        Cxt.defineCmdlineVariables(GlobalDefines, SM));
 
   // Invalid variable name.
   GlobalDefines.clear();
   GlobalDefines.emplace_back(std::string("18LocalVar=18"));
-  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  expectDiagnosticError("invalid variable name",
+                        Cxt.defineCmdlineVariables(GlobalDefines, SM));
   GlobalDefines.clear();
   GlobalDefines.emplace_back(std::string("#18LocalNumVar=18"));
-  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  expectDiagnosticError("invalid variable name",
+                        Cxt.defineCmdlineVariables(GlobalDefines, SM));
 
   // Name conflict between pattern and numeric variable.
   GlobalDefines.clear();
   GlobalDefines.emplace_back(std::string("LocalVar=18"));
   GlobalDefines.emplace_back(std::string("#LocalVar=36"));
-  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  expectDiagnosticError("string variable with name 'LocalVar' already exists",
+                        Cxt.defineCmdlineVariables(GlobalDefines, SM));
   Cxt = FileCheckPatternContext();
   GlobalDefines.clear();
   GlobalDefines.emplace_back(std::string("#LocalNumVar=18"));
   GlobalDefines.emplace_back(std::string("LocalNumVar=36"));
-  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  expectDiagnosticError(
+      "numeric variable with name 'LocalNumVar' already exists",
+      Cxt.defineCmdlineVariables(GlobalDefines, SM));
   Cxt = FileCheckPatternContext();
 
   // Invalid numeric value for numeric variable.
   GlobalDefines.clear();
   GlobalDefines.emplace_back(std::string("#LocalNumVar=x"));
-  EXPECT_TRUE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  expectUndefErrors({"x"}, Cxt.defineCmdlineVariables(GlobalDefines, SM));
 
   // Define local variables from command-line.
   GlobalDefines.clear();
@@ -527,7 +566,7 @@ TEST_F(FileCheckTest, FileCheckContext) {
   GlobalDefines.emplace_back(std::string("EmptyVar="));
   GlobalDefines.emplace_back(std::string("#LocalNumVar1=18"));
   GlobalDefines.emplace_back(std::string("#LocalNumVar2=LocalNumVar1+2"));
-  ASSERT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  ASSERT_THAT_ERROR(Cxt.defineCmdlineVariables(GlobalDefines, SM), Succeeded());
 
   // Create @LINE pseudo numeric variable and check it is present by matching
   // it.
@@ -537,7 +576,7 @@ TEST_F(FileCheckTest, FileCheckContext) {
   Cxt.createLineVariable();
   ASSERT_FALSE(P.parsePattern("[[@LINE]]", "CHECK", SM, Req));
   size_t MatchLen;
-  ASSERT_FALSE(errorToBool(P.match("1", MatchLen, SM).takeError()));
+  ASSERT_THAT_EXPECTED(P.match("1", MatchLen, SM), Succeeded());
 
 #ifndef NDEBUG
   // Recreating @LINE pseudo numeric variable fails.
@@ -558,49 +597,50 @@ TEST_F(FileCheckTest, FileCheckContext) {
       P.parseNumericSubstitutionBlock(LocalNumVar1Ref, DefinedNumericVariable,
                                       /*IsLegacyLineExpr=*/false, LineNumber,
                                       &Cxt, SM);
-  ASSERT_TRUE(bool(LocalVar));
+  ASSERT_THAT_EXPECTED(LocalVar, Succeeded());
   EXPECT_EQ(*LocalVar, "FOO");
   Expected<StringRef> EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
   Expected<StringRef> UnknownVar = Cxt.getPatternVarValue(UnknownVarStr);
-  ASSERT_TRUE(bool(ExpressionASTPointer));
+  ASSERT_THAT_EXPECTED(ExpressionASTPointer, Succeeded());
   Expected<uint64_t> ExpressionVal = (*ExpressionASTPointer)->eval();
-  ASSERT_TRUE(bool(ExpressionVal));
+  ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded());
   EXPECT_EQ(*ExpressionVal, 18U);
   ExpressionASTPointer = P.parseNumericSubstitutionBlock(
       LocalNumVar2Ref, DefinedNumericVariable,
       /*IsLegacyLineExpr=*/false, LineNumber, &Cxt, SM);
-  ASSERT_TRUE(bool(ExpressionASTPointer));
+  ASSERT_THAT_EXPECTED(ExpressionASTPointer, Succeeded());
   ExpressionVal = (*ExpressionASTPointer)->eval();
-  ASSERT_TRUE(bool(ExpressionVal));
+  ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded());
   EXPECT_EQ(*ExpressionVal, 20U);
-  ASSERT_TRUE(bool(EmptyVar));
+  ASSERT_THAT_EXPECTED(EmptyVar, Succeeded());
   EXPECT_EQ(*EmptyVar, "");
-  EXPECT_TRUE(errorToBool(UnknownVar.takeError()));
+  expectUndefErrors({UnknownVarStr}, UnknownVar.takeError());
 
   // Clear local variables and check they become absent.
   Cxt.clearLocalVars();
   LocalVar = Cxt.getPatternVarValue(LocalVarStr);
-  EXPECT_TRUE(errorToBool(LocalVar.takeError()));
+  expectUndefErrors({LocalVarStr}, LocalVar.takeError());
   // Check a numeric expression's evaluation fails if called after clearing of
   // local variables, if it was created before. This is important because local
   // variable clearing due to --enable-var-scope happens after numeric
   // expressions are linked to the numeric variables they use.
-  EXPECT_TRUE(errorToBool((*ExpressionASTPointer)->eval().takeError()));
+  expectUndefErrors({"LocalNumVar2"},
+                    (*ExpressionASTPointer)->eval().takeError());
   P = Pattern(Check::CheckPlain, &Cxt, ++LineNumber);
   ExpressionASTPointer = P.parseNumericSubstitutionBlock(
       LocalNumVar1Ref, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
       LineNumber, &Cxt, SM);
-  ASSERT_TRUE(bool(ExpressionASTPointer));
+  ASSERT_THAT_EXPECTED(ExpressionASTPointer, Succeeded());
   ExpressionVal = (*ExpressionASTPointer)->eval();
-  EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
+  expectUndefErrors({"LocalNumVar1"}, ExpressionVal.takeError());
   ExpressionASTPointer = P.parseNumericSubstitutionBlock(
       LocalNumVar2Ref, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
       LineNumber, &Cxt, SM);
-  ASSERT_TRUE(bool(ExpressionASTPointer));
+  ASSERT_THAT_EXPECTED(ExpressionASTPointer, Succeeded());
   ExpressionVal = (*ExpressionASTPointer)->eval();
-  EXPECT_TRUE(errorToBool(ExpressionVal.takeError()));
+  expectUndefErrors({"LocalNumVar2"}, ExpressionVal.takeError());
   EmptyVar = Cxt.getPatternVarValue(EmptyVarStr);
-  EXPECT_TRUE(errorToBool(EmptyVar.takeError()));
+  expectUndefErrors({"EmptyVar"}, EmptyVar.takeError());
   // Clear again because parseNumericSubstitutionBlock would have created a
   // dummy variable and stored it in GlobalNumericVariableTable.
   Cxt.clearLocalVars();
@@ -608,31 +648,31 @@ TEST_F(FileCheckTest, FileCheckContext) {
   // Redefine global variables and check variables are defined again.
   GlobalDefines.emplace_back(std::string("$GlobalVar=BAR"));
   GlobalDefines.emplace_back(std::string("#$GlobalNumVar=36"));
-  ASSERT_FALSE(errorToBool(Cxt.defineCmdlineVariables(GlobalDefines, SM)));
+  ASSERT_THAT_ERROR(Cxt.defineCmdlineVariables(GlobalDefines, SM), Succeeded());
   StringRef GlobalVarStr = "$GlobalVar";
   StringRef GlobalNumVarRef = bufferize(SM, "$GlobalNumVar");
   Expected<StringRef> GlobalVar = Cxt.getPatternVarValue(GlobalVarStr);
-  ASSERT_TRUE(bool(GlobalVar));
+  ASSERT_THAT_EXPECTED(GlobalVar, Succeeded());
   EXPECT_EQ(*GlobalVar, "BAR");
   P = Pattern(Check::CheckPlain, &Cxt, ++LineNumber);
   ExpressionASTPointer = P.parseNumericSubstitutionBlock(
       GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
       LineNumber, &Cxt, SM);
-  ASSERT_TRUE(bool(ExpressionASTPointer));
+  ASSERT_THAT_EXPECTED(ExpressionASTPointer, Succeeded());
   ExpressionVal = (*ExpressionASTPointer)->eval();
-  ASSERT_TRUE(bool(ExpressionVal));
+  ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded());
   EXPECT_EQ(*ExpressionVal, 36U);
 
   // Clear local variables and check global variables remain defined.
   Cxt.clearLocalVars();
-  EXPECT_FALSE(errorToBool(Cxt.getPatternVarValue(GlobalVarStr).takeError()));
+  EXPECT_THAT_EXPECTED(Cxt.getPatternVarValue(GlobalVarStr), Succeeded());
   P = Pattern(Check::CheckPlain, &Cxt, ++LineNumber);
   ExpressionASTPointer = P.parseNumericSubstitutionBlock(
       GlobalNumVarRef, DefinedNumericVariable, /*IsLegacyLineExpr=*/false,
       LineNumber, &Cxt, SM);
-  ASSERT_TRUE(bool(ExpressionASTPointer));
+  ASSERT_THAT_EXPECTED(ExpressionASTPointer, Succeeded());
   ExpressionVal = (*ExpressionASTPointer)->eval();
-  ASSERT_TRUE(bool(ExpressionVal));
+  ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded());
   EXPECT_EQ(*ExpressionVal, 36U);
 }
 } // namespace


        


More information about the llvm-commits mailing list