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<std::unique_ptr<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, Quit) { 51 QueryRef Q = parse("quit"); 52 ASSERT_TRUE(isa<QuitQuery>(Q)); 53 54 Q = parse("quit me"); 55 ASSERT_TRUE(isa<InvalidQuery>(Q)); 56 EXPECT_EQ("unexpected extra input: ' me'", cast<InvalidQuery>(Q)->ErrStr); 57 } 58 59 TEST_F(QueryParserTest, Set) { 60 QueryRef Q = parse("set"); 61 ASSERT_TRUE(isa<InvalidQuery>(Q)); 62 EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr); 63 64 Q = parse("set foo bar"); 65 ASSERT_TRUE(isa<InvalidQuery>(Q)); 66 EXPECT_EQ("unknown variable: 'foo'", cast<InvalidQuery>(Q)->ErrStr); 67 68 Q = parse("set output"); 69 ASSERT_TRUE(isa<InvalidQuery>(Q)); 70 EXPECT_EQ("expected 'diag', 'print' or 'dump', got ''", 71 cast<InvalidQuery>(Q)->ErrStr); 72 73 Q = parse("set bind-root true foo"); 74 ASSERT_TRUE(isa<InvalidQuery>(Q)); 75 EXPECT_EQ("unexpected extra input: ' foo'", cast<InvalidQuery>(Q)->ErrStr); 76 77 Q = parse("set output foo"); 78 ASSERT_TRUE(isa<InvalidQuery>(Q)); 79 EXPECT_EQ("expected 'diag', 'print' or 'dump', got 'foo'", 80 cast<InvalidQuery>(Q)->ErrStr); 81 82 Q = parse("set output dump"); 83 ASSERT_TRUE(isa<SetQuery<OutputKind> >(Q)); 84 EXPECT_EQ(&QuerySession::OutKind, cast<SetQuery<OutputKind> >(Q)->Var); 85 EXPECT_EQ(OK_Dump, cast<SetQuery<OutputKind> >(Q)->Value); 86 87 Q = parse("set bind-root foo"); 88 ASSERT_TRUE(isa<InvalidQuery>(Q)); 89 EXPECT_EQ("expected 'true' or 'false', got 'foo'", 90 cast<InvalidQuery>(Q)->ErrStr); 91 92 Q = parse("set bind-root true"); 93 ASSERT_TRUE(isa<SetQuery<bool> >(Q)); 94 EXPECT_EQ(&QuerySession::BindRoot, cast<SetQuery<bool> >(Q)->Var); 95 EXPECT_EQ(true, cast<SetQuery<bool> >(Q)->Value); 96 } 97 98 TEST_F(QueryParserTest, Match) { 99 QueryRef Q = parse("match decl()"); 100 ASSERT_TRUE(isa<MatchQuery>(Q)); 101 EXPECT_TRUE(cast<MatchQuery>(Q)->Matcher.canConvertTo<Decl>()); 102 103 Q = parse("m stmt()"); 104 ASSERT_TRUE(isa<MatchQuery>(Q)); 105 EXPECT_TRUE(cast<MatchQuery>(Q)->Matcher.canConvertTo<Stmt>()); 106 } 107 108 TEST_F(QueryParserTest, LetUnlet) { 109 QueryRef Q = parse("let foo decl()"); 110 ASSERT_TRUE(isa<LetQuery>(Q)); 111 EXPECT_EQ("foo", cast<LetQuery>(Q)->Name); 112 EXPECT_TRUE(cast<LetQuery>(Q)->Value.isMatcher()); 113 EXPECT_TRUE(cast<LetQuery>(Q)->Value.getMatcher().hasTypedMatcher<Decl>()); 114 115 Q = parse("l foo decl()"); 116 ASSERT_TRUE(isa<LetQuery>(Q)); 117 EXPECT_EQ("foo", cast<LetQuery>(Q)->Name); 118 EXPECT_TRUE(cast<LetQuery>(Q)->Value.isMatcher()); 119 EXPECT_TRUE(cast<LetQuery>(Q)->Value.getMatcher().hasTypedMatcher<Decl>()); 120 121 Q = parse("let bar \"str\""); 122 ASSERT_TRUE(isa<LetQuery>(Q)); 123 EXPECT_EQ("bar", cast<LetQuery>(Q)->Name); 124 EXPECT_TRUE(cast<LetQuery>(Q)->Value.isString()); 125 EXPECT_EQ("str", cast<LetQuery>(Q)->Value.getString()); 126 127 Q = parse("let"); 128 ASSERT_TRUE(isa<InvalidQuery>(Q)); 129 EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr); 130 131 Q = parse("unlet x"); 132 ASSERT_TRUE(isa<LetQuery>(Q)); 133 EXPECT_EQ("x", cast<LetQuery>(Q)->Name); 134 EXPECT_FALSE(cast<LetQuery>(Q)->Value.hasValue()); 135 136 Q = parse("unlet"); 137 ASSERT_TRUE(isa<InvalidQuery>(Q)); 138 EXPECT_EQ("expected variable name", cast<InvalidQuery>(Q)->ErrStr); 139 140 Q = parse("unlet x bad_data"); 141 ASSERT_TRUE(isa<InvalidQuery>(Q)); 142 EXPECT_EQ("unexpected extra input: ' bad_data'", 143 cast<InvalidQuery>(Q)->ErrStr); 144 } 145 146 TEST_F(QueryParserTest, Complete) { 147 std::vector<llvm::LineEditor::Completion> Comps = 148 QueryParser::complete("", 0, QS); 149 ASSERT_EQ(6u, Comps.size()); 150 EXPECT_EQ("help ", Comps[0].TypedText); 151 EXPECT_EQ("help", Comps[0].DisplayText); 152 EXPECT_EQ("let ", Comps[1].TypedText); 153 EXPECT_EQ("let", Comps[1].DisplayText); 154 EXPECT_EQ("match ", Comps[2].TypedText); 155 EXPECT_EQ("match", Comps[2].DisplayText); 156 EXPECT_EQ("set ", Comps[3].TypedText); 157 EXPECT_EQ("set", Comps[3].DisplayText); 158 EXPECT_EQ("unlet ", Comps[4].TypedText); 159 EXPECT_EQ("unlet", Comps[4].DisplayText); 160 EXPECT_EQ("quit", Comps[5].DisplayText); 161 EXPECT_EQ("quit ", Comps[5].TypedText); 162 163 Comps = QueryParser::complete("set o", 5, QS); 164 ASSERT_EQ(1u, Comps.size()); 165 EXPECT_EQ("utput ", Comps[0].TypedText); 166 EXPECT_EQ("output", Comps[0].DisplayText); 167 168 Comps = QueryParser::complete("match while", 11, QS); 169 ASSERT_EQ(1u, Comps.size()); 170 EXPECT_EQ("Stmt(", Comps[0].TypedText); 171 EXPECT_EQ("Matcher<Stmt> whileStmt(Matcher<WhileStmt>...)", 172 Comps[0].DisplayText); 173 } 174