1 //===---- QueryParserTest.cpp - clang-query test --------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "QueryParser.h" 11 #include "Query.h" 12 #include "QuerySession.h" 13 #include "llvm/LineEditor/LineEditor.h" 14 #include "gtest/gtest.h" 15 16 using namespace clang; 17 using namespace clang::query; 18 19 class QueryParserTest : public ::testing::Test { 20 protected: 21 QueryParserTest() : QS(llvm::ArrayRef<ASTUnit *>()) {} 22 QueryRef parse(StringRef Code) { return QueryParser::parse(Code, QS); } 23 24 QuerySession QS; 25 }; 26 27 TEST_F(QueryParserTest, NoOp) { 28 QueryRef Q = parse(""); 29 EXPECT_TRUE(isa<NoOpQuery>(Q)); 30 31 Q = parse("\n"); 32 EXPECT_TRUE(isa<NoOpQuery>(Q)); 33 } 34 35 TEST_F(QueryParserTest, Invalid) { 36 QueryRef Q = parse("foo"); 37 ASSERT_TRUE(isa<InvalidQuery>(Q)); 38 EXPECT_EQ("unknown command: foo", cast<InvalidQuery>(Q)->ErrStr); 39 } 40 41 TEST_F(QueryParserTest, Help) { 42 QueryRef Q = parse("help"); 43 ASSERT_TRUE(isa<HelpQuery>(Q)); 44 45 Q = parse("help me"); 46 ASSERT_TRUE(isa<InvalidQuery>(Q)); 47 EXPECT_EQ("unexpected extra input: ' me'", cast<InvalidQuery>(Q)->ErrStr); 48 } 49 50 TEST_F(QueryParserTest, Set) { 51 QueryRef Q = parse("set"); 52 ASSERT_TRUE(isa<InvalidQuery>(Q)); 53 EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr); 54 55 Q = parse("set foo bar"); 56 ASSERT_TRUE(isa<InvalidQuery>(Q)); 57 EXPECT_EQ("unknown variable: 'foo'", cast<InvalidQuery>(Q)->ErrStr); 58 59 Q = parse("set output"); 60 ASSERT_TRUE(isa<InvalidQuery>(Q)); 61 EXPECT_EQ("expected 'diag', 'print' or 'dump', got ''", 62 cast<InvalidQuery>(Q)->ErrStr); 63 64 Q = parse("set bind-root true foo"); 65 ASSERT_TRUE(isa<InvalidQuery>(Q)); 66 EXPECT_EQ("unexpected extra input: ' foo'", cast<InvalidQuery>(Q)->ErrStr); 67 68 Q = parse("set output foo"); 69 ASSERT_TRUE(isa<InvalidQuery>(Q)); 70 EXPECT_EQ("expected 'diag', 'print' or 'dump', got 'foo'", 71 cast<InvalidQuery>(Q)->ErrStr); 72 73 Q = parse("set output dump"); 74 ASSERT_TRUE(isa<SetQuery<OutputKind> >(Q)); 75 EXPECT_EQ(&QuerySession::OutKind, cast<SetQuery<OutputKind> >(Q)->Var); 76 EXPECT_EQ(OK_Dump, cast<SetQuery<OutputKind> >(Q)->Value); 77 78 Q = parse("set bind-root foo"); 79 ASSERT_TRUE(isa<InvalidQuery>(Q)); 80 EXPECT_EQ("expected 'true' or 'false', got 'foo'", 81 cast<InvalidQuery>(Q)->ErrStr); 82 83 Q = parse("set bind-root true"); 84 ASSERT_TRUE(isa<SetQuery<bool> >(Q)); 85 EXPECT_EQ(&QuerySession::BindRoot, cast<SetQuery<bool> >(Q)->Var); 86 EXPECT_EQ(true, cast<SetQuery<bool> >(Q)->Value); 87 } 88 89 TEST_F(QueryParserTest, Match) { 90 QueryRef Q = parse("match decl()"); 91 ASSERT_TRUE(isa<MatchQuery>(Q)); 92 EXPECT_TRUE(cast<MatchQuery>(Q)->Matcher.canConvertTo<Decl>()); 93 94 Q = parse("m stmt()"); 95 ASSERT_TRUE(isa<MatchQuery>(Q)); 96 EXPECT_TRUE(cast<MatchQuery>(Q)->Matcher.canConvertTo<Stmt>()); 97 } 98 99 TEST_F(QueryParserTest, LetUnlet) { 100 QueryRef Q = parse("let foo decl()"); 101 ASSERT_TRUE(isa<LetQuery>(Q)); 102 EXPECT_EQ("foo", cast<LetQuery>(Q)->Name); 103 EXPECT_TRUE(cast<LetQuery>(Q)->Value.isMatcher()); 104 EXPECT_TRUE(cast<LetQuery>(Q)->Value.getMatcher().hasTypedMatcher<Decl>()); 105 106 Q = parse("let bar \"str\""); 107 ASSERT_TRUE(isa<LetQuery>(Q)); 108 EXPECT_EQ("bar", cast<LetQuery>(Q)->Name); 109 EXPECT_TRUE(cast<LetQuery>(Q)->Value.isString()); 110 EXPECT_EQ("str", cast<LetQuery>(Q)->Value.getString()); 111 112 Q = parse("let"); 113 ASSERT_TRUE(isa<InvalidQuery>(Q)); 114 EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr); 115 116 Q = parse("unlet x"); 117 ASSERT_TRUE(isa<LetQuery>(Q)); 118 EXPECT_EQ("x", cast<LetQuery>(Q)->Name); 119 EXPECT_FALSE(cast<LetQuery>(Q)->Value.hasValue()); 120 121 Q = parse("unlet"); 122 ASSERT_TRUE(isa<InvalidQuery>(Q)); 123 EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr); 124 125 Q = parse("unlet x bad_data"); 126 ASSERT_TRUE(isa<InvalidQuery>(Q)); 127 EXPECT_EQ("unexpected extra input: ' bad_data'", 128 cast<InvalidQuery>(Q)->ErrStr); 129 } 130 131 TEST_F(QueryParserTest, Complete) { 132 std::vector<llvm::LineEditor::Completion> Comps = 133 QueryParser::complete("", 0, QS); 134 ASSERT_EQ(5u, Comps.size()); 135 EXPECT_EQ("help ", Comps[0].TypedText); 136 EXPECT_EQ("help", Comps[0].DisplayText); 137 EXPECT_EQ("let ", Comps[1].TypedText); 138 EXPECT_EQ("let", Comps[1].DisplayText); 139 EXPECT_EQ("match ", Comps[2].TypedText); 140 EXPECT_EQ("match", Comps[2].DisplayText); 141 EXPECT_EQ("set ", Comps[3].TypedText); 142 EXPECT_EQ("set", Comps[3].DisplayText); 143 EXPECT_EQ("unlet ", Comps[4].TypedText); 144 EXPECT_EQ("unlet", Comps[4].DisplayText); 145 146 Comps = QueryParser::complete("set o", 5, QS); 147 ASSERT_EQ(1u, Comps.size()); 148 EXPECT_EQ("utput ", Comps[0].TypedText); 149 EXPECT_EQ("output", Comps[0].DisplayText); 150 151 Comps = QueryParser::complete("match while", 11, QS); 152 ASSERT_EQ(1u, Comps.size()); 153 EXPECT_EQ("Stmt(", Comps[0].TypedText); 154 EXPECT_EQ("Matcher<Stmt> whileStmt(Matcher<WhileStmt>...)", 155 Comps[0].DisplayText); 156 } 157