1 //===- TrigramIndexTest.cpp - Unit tests for TrigramIndex -----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/Support/TrigramIndex.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "gtest/gtest.h"
12 
13 #include <string>
14 #include <vector>
15 
16 using namespace llvm;
17 
18 namespace {
19 
20 class TrigramIndexTest : public ::testing::Test {
21 protected:
makeTrigramIndex(std::vector<std::string> Rules)22   std::unique_ptr<TrigramIndex> makeTrigramIndex(
23       std::vector<std::string> Rules) {
24     std::unique_ptr<TrigramIndex> TI =
25         std::make_unique<TrigramIndex>();
26     for (auto &Rule : Rules)
27       TI->insert(Rule);
28     return TI;
29   }
30 };
31 
TEST_F(TrigramIndexTest,Empty)32 TEST_F(TrigramIndexTest, Empty) {
33   std::unique_ptr<TrigramIndex> TI =
34       makeTrigramIndex({});
35   EXPECT_FALSE(TI->isDefeated());
36   EXPECT_TRUE(TI->isDefinitelyOut("foo"));
37 }
38 
TEST_F(TrigramIndexTest,Basic)39 TEST_F(TrigramIndexTest, Basic) {
40   std::unique_ptr<TrigramIndex> TI =
41       makeTrigramIndex({"*hello*", "*wor.d*"});
42   EXPECT_FALSE(TI->isDefeated());
43   EXPECT_TRUE(TI->isDefinitelyOut("foo"));
44 }
45 
TEST_F(TrigramIndexTest,NoTrigramsInRules)46 TEST_F(TrigramIndexTest, NoTrigramsInRules) {
47   std::unique_ptr<TrigramIndex> TI =
48       makeTrigramIndex({"b.r", "za*az"});
49   EXPECT_TRUE(TI->isDefeated());
50   EXPECT_FALSE(TI->isDefinitelyOut("foo"));
51   EXPECT_FALSE(TI->isDefinitelyOut("bar"));
52   EXPECT_FALSE(TI->isDefinitelyOut("zakaz"));
53 }
54 
TEST_F(TrigramIndexTest,NoTrigramsInARule)55 TEST_F(TrigramIndexTest, NoTrigramsInARule) {
56   std::unique_ptr<TrigramIndex> TI =
57       makeTrigramIndex({"*hello*", "*wo.ld*"});
58   EXPECT_TRUE(TI->isDefeated());
59   EXPECT_FALSE(TI->isDefinitelyOut("foo"));
60 }
61 
TEST_F(TrigramIndexTest,RepetitiveRule)62 TEST_F(TrigramIndexTest, RepetitiveRule) {
63   std::unique_ptr<TrigramIndex> TI =
64       makeTrigramIndex({"*bar*bar*bar*bar*bar", "bar*bar"});
65   EXPECT_FALSE(TI->isDefeated());
66   EXPECT_TRUE(TI->isDefinitelyOut("foo"));
67   EXPECT_TRUE(TI->isDefinitelyOut("bar"));
68   EXPECT_FALSE(TI->isDefinitelyOut("barbara"));
69   EXPECT_FALSE(TI->isDefinitelyOut("bar+bar"));
70 }
71 
TEST_F(TrigramIndexTest,PopularTrigram)72 TEST_F(TrigramIndexTest, PopularTrigram) {
73   std::unique_ptr<TrigramIndex> TI =
74       makeTrigramIndex({"*aaa*", "*aaaa*", "*aaaaa*", "*aaaaa*", "*aaaaaa*"});
75   EXPECT_TRUE(TI->isDefeated());
76 }
77 
TEST_F(TrigramIndexTest,PopularTrigram2)78 TEST_F(TrigramIndexTest, PopularTrigram2) {
79   std::unique_ptr<TrigramIndex> TI =
80       makeTrigramIndex({"class1.h", "class2.h", "class3.h", "class4.h", "class.h"});
81   EXPECT_TRUE(TI->isDefeated());
82 }
83 
TEST_F(TrigramIndexTest,TooComplicatedRegex)84 TEST_F(TrigramIndexTest, TooComplicatedRegex) {
85   std::unique_ptr<TrigramIndex> TI =
86       makeTrigramIndex({"[0-9]+"});
87   EXPECT_TRUE(TI->isDefeated());
88 }
89 
TEST_F(TrigramIndexTest,TooComplicatedRegex2)90 TEST_F(TrigramIndexTest, TooComplicatedRegex2) {
91   std::unique_ptr<TrigramIndex> TI =
92       makeTrigramIndex({"foo|bar"});
93   EXPECT_TRUE(TI->isDefeated());
94 }
95 
TEST_F(TrigramIndexTest,EscapedSymbols)96 TEST_F(TrigramIndexTest, EscapedSymbols) {
97   std::unique_ptr<TrigramIndex> TI =
98       makeTrigramIndex({"*c\\+\\+*", "*hello\\\\world*", "a\\tb", "a\\0b"});
99   EXPECT_FALSE(TI->isDefeated());
100   EXPECT_FALSE(TI->isDefinitelyOut("c++"));
101   EXPECT_TRUE(TI->isDefinitelyOut("c\\+\\+"));
102   EXPECT_FALSE(TI->isDefinitelyOut("hello\\world"));
103   EXPECT_TRUE(TI->isDefinitelyOut("hello\\\\world"));
104   EXPECT_FALSE(TI->isDefinitelyOut("atb"));
105   EXPECT_TRUE(TI->isDefinitelyOut("a\\tb"));
106   EXPECT_TRUE(TI->isDefinitelyOut("a\tb"));
107   EXPECT_FALSE(TI->isDefinitelyOut("a0b"));
108 }
109 
TEST_F(TrigramIndexTest,Backreference1)110 TEST_F(TrigramIndexTest, Backreference1) {
111   std::unique_ptr<TrigramIndex> TI =
112       makeTrigramIndex({"*foo\\1*"});
113   EXPECT_TRUE(TI->isDefeated());
114 }
115 
TEST_F(TrigramIndexTest,Backreference2)116 TEST_F(TrigramIndexTest, Backreference2) {
117   std::unique_ptr<TrigramIndex> TI =
118       makeTrigramIndex({"*foo\\2*"});
119   EXPECT_TRUE(TI->isDefeated());
120 }
121 
TEST_F(TrigramIndexTest,Sequence)122 TEST_F(TrigramIndexTest, Sequence) {
123   std::unique_ptr<TrigramIndex> TI =
124       makeTrigramIndex({"class1.h", "class2.h", "class3.h", "class4.h"});
125   EXPECT_FALSE(TI->isDefeated());
126   EXPECT_FALSE(TI->isDefinitelyOut("class1"));
127   EXPECT_TRUE(TI->isDefinitelyOut("class.h"));
128   EXPECT_TRUE(TI->isDefinitelyOut("class"));
129 }
130 
131 }  // namespace
132