• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2010 The RE2 Authors.  All Rights Reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 
5 #include "re2/set.h"
6 
7 #include <stddef.h>
8 
9 #include <utility>
10 #include <vector>
11 
12 #include "gtest/gtest.h"
13 #include "re2/re2.h"
14 
15 namespace re2 {
16 
TEST(Set,Unanchored)17 TEST(Set, Unanchored) {
18   RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);
19 
20   ASSERT_EQ(s.Add("foo", NULL), 0);
21   ASSERT_EQ(s.Add("(", NULL), -1);
22   ASSERT_EQ(s.Add("bar", NULL), 1);
23   ASSERT_EQ(s.Compile(), true);
24 
25   ASSERT_EQ(s.Match("foobar", NULL), true);
26   ASSERT_EQ(s.Match("fooba", NULL), true);
27   ASSERT_EQ(s.Match("oobar", NULL), true);
28 
29   std::vector<int> v;
30   ASSERT_EQ(s.Match("foobar", &v), true);
31   ASSERT_EQ(v.size(), size_t{2});
32   ASSERT_EQ(v[0], 0);
33   ASSERT_EQ(v[1], 1);
34 
35   ASSERT_EQ(s.Match("fooba", &v), true);
36   ASSERT_EQ(v.size(), size_t{1});
37   ASSERT_EQ(v[0], 0);
38 
39   ASSERT_EQ(s.Match("oobar", &v), true);
40   ASSERT_EQ(v.size(), size_t{1});
41   ASSERT_EQ(v[0], 1);
42 }
43 
TEST(Set,UnanchoredFactored)44 TEST(Set, UnanchoredFactored) {
45   RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);
46 
47   ASSERT_EQ(s.Add("foo", NULL), 0);
48   ASSERT_EQ(s.Add("(", NULL), -1);
49   ASSERT_EQ(s.Add("foobar", NULL), 1);
50   ASSERT_EQ(s.Compile(), true);
51 
52   ASSERT_EQ(s.Match("foobar", NULL), true);
53   ASSERT_EQ(s.Match("obarfoobaroo", NULL), true);
54   ASSERT_EQ(s.Match("fooba", NULL), true);
55   ASSERT_EQ(s.Match("oobar", NULL), false);
56 
57   std::vector<int> v;
58   ASSERT_EQ(s.Match("foobar", &v), true);
59   ASSERT_EQ(v.size(), size_t{2});
60   ASSERT_EQ(v[0], 0);
61   ASSERT_EQ(v[1], 1);
62 
63   ASSERT_EQ(s.Match("obarfoobaroo", &v), true);
64   ASSERT_EQ(v.size(), size_t{2});
65   ASSERT_EQ(v[0], 0);
66   ASSERT_EQ(v[1], 1);
67 
68   ASSERT_EQ(s.Match("fooba", &v), true);
69   ASSERT_EQ(v.size(), size_t{1});
70   ASSERT_EQ(v[0], 0);
71 
72   ASSERT_EQ(s.Match("oobar", &v), false);
73   ASSERT_EQ(v.size(), size_t{0});
74 }
75 
TEST(Set,UnanchoredDollar)76 TEST(Set, UnanchoredDollar) {
77   RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);
78 
79   ASSERT_EQ(s.Add("foo$", NULL), 0);
80   ASSERT_EQ(s.Compile(), true);
81 
82   ASSERT_EQ(s.Match("foo", NULL), true);
83   ASSERT_EQ(s.Match("foobar", NULL), false);
84 
85   std::vector<int> v;
86   ASSERT_EQ(s.Match("foo", &v), true);
87   ASSERT_EQ(v.size(), size_t{1});
88   ASSERT_EQ(v[0], 0);
89 
90   ASSERT_EQ(s.Match("foobar", &v), false);
91   ASSERT_EQ(v.size(), size_t{0});
92 }
93 
TEST(Set,UnanchoredWordBoundary)94 TEST(Set, UnanchoredWordBoundary) {
95   RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);
96 
97   ASSERT_EQ(s.Add("foo\\b", NULL), 0);
98   ASSERT_EQ(s.Compile(), true);
99 
100   ASSERT_EQ(s.Match("foo", NULL), true);
101   ASSERT_EQ(s.Match("foobar", NULL), false);
102   ASSERT_EQ(s.Match("foo bar", NULL), true);
103 
104   std::vector<int> v;
105   ASSERT_EQ(s.Match("foo", &v), true);
106   ASSERT_EQ(v.size(), size_t{1});
107   ASSERT_EQ(v[0], 0);
108 
109   ASSERT_EQ(s.Match("foobar", &v), false);
110   ASSERT_EQ(v.size(), size_t{0});
111 
112   ASSERT_EQ(s.Match("foo bar", &v), true);
113   ASSERT_EQ(v.size(), size_t{1});
114   ASSERT_EQ(v[0], 0);
115 }
116 
TEST(Set,Anchored)117 TEST(Set, Anchored) {
118   RE2::Set s(RE2::DefaultOptions, RE2::ANCHOR_BOTH);
119 
120   ASSERT_EQ(s.Add("foo", NULL), 0);
121   ASSERT_EQ(s.Add("(", NULL), -1);
122   ASSERT_EQ(s.Add("bar", NULL), 1);
123   ASSERT_EQ(s.Compile(), true);
124 
125   ASSERT_EQ(s.Match("foobar", NULL), false);
126   ASSERT_EQ(s.Match("fooba", NULL), false);
127   ASSERT_EQ(s.Match("oobar", NULL), false);
128   ASSERT_EQ(s.Match("foo", NULL), true);
129   ASSERT_EQ(s.Match("bar", NULL), true);
130 
131   std::vector<int> v;
132   ASSERT_EQ(s.Match("foobar", &v), false);
133   ASSERT_EQ(v.size(), size_t{0});
134 
135   ASSERT_EQ(s.Match("fooba", &v), false);
136   ASSERT_EQ(v.size(), size_t{0});
137 
138   ASSERT_EQ(s.Match("oobar", &v), false);
139   ASSERT_EQ(v.size(), size_t{0});
140 
141   ASSERT_EQ(s.Match("foo", &v), true);
142   ASSERT_EQ(v.size(), size_t{1});
143   ASSERT_EQ(v[0], 0);
144 
145   ASSERT_EQ(s.Match("bar", &v), true);
146   ASSERT_EQ(v.size(), size_t{1});
147   ASSERT_EQ(v[0], 1);
148 }
149 
TEST(Set,EmptyUnanchored)150 TEST(Set, EmptyUnanchored) {
151   RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);
152 
153   ASSERT_EQ(s.Compile(), true);
154 
155   ASSERT_EQ(s.Match("", NULL), false);
156   ASSERT_EQ(s.Match("foobar", NULL), false);
157 
158   std::vector<int> v;
159   ASSERT_EQ(s.Match("", &v), false);
160   ASSERT_EQ(v.size(), size_t{0});
161 
162   ASSERT_EQ(s.Match("foobar", &v), false);
163   ASSERT_EQ(v.size(), size_t{0});
164 }
165 
TEST(Set,EmptyAnchored)166 TEST(Set, EmptyAnchored) {
167   RE2::Set s(RE2::DefaultOptions, RE2::ANCHOR_BOTH);
168 
169   ASSERT_EQ(s.Compile(), true);
170 
171   ASSERT_EQ(s.Match("", NULL), false);
172   ASSERT_EQ(s.Match("foobar", NULL), false);
173 
174   std::vector<int> v;
175   ASSERT_EQ(s.Match("", &v), false);
176   ASSERT_EQ(v.size(), size_t{0});
177 
178   ASSERT_EQ(s.Match("foobar", &v), false);
179   ASSERT_EQ(v.size(), size_t{0});
180 }
181 
TEST(Set,Prefix)182 TEST(Set, Prefix) {
183   RE2::Set s(RE2::DefaultOptions, RE2::ANCHOR_BOTH);
184 
185   ASSERT_EQ(s.Add("/prefix/\\d*", NULL), 0);
186   ASSERT_EQ(s.Compile(), true);
187 
188   ASSERT_EQ(s.Match("/prefix", NULL), false);
189   ASSERT_EQ(s.Match("/prefix/", NULL), true);
190   ASSERT_EQ(s.Match("/prefix/42", NULL), true);
191 
192   std::vector<int> v;
193   ASSERT_EQ(s.Match("/prefix", &v), false);
194   ASSERT_EQ(v.size(), size_t{0});
195 
196   ASSERT_EQ(s.Match("/prefix/", &v), true);
197   ASSERT_EQ(v.size(), size_t{1});
198   ASSERT_EQ(v[0], 0);
199 
200   ASSERT_EQ(s.Match("/prefix/42", &v), true);
201   ASSERT_EQ(v.size(), size_t{1});
202   ASSERT_EQ(v[0], 0);
203 }
204 
TEST(Set,MoveSemantics)205 TEST(Set, MoveSemantics) {
206   RE2::Set s1(RE2::DefaultOptions, RE2::UNANCHORED);
207   ASSERT_EQ(s1.Add("foo\\d+", NULL), 0);
208   ASSERT_EQ(s1.Compile(), true);
209   ASSERT_EQ(s1.Match("abc foo1 xyz", NULL), true);
210   ASSERT_EQ(s1.Match("abc bar2 xyz", NULL), false);
211 
212   // The moved-to object should do what the moved-from object did.
213   RE2::Set s2 = std::move(s1);
214   ASSERT_EQ(s2.Match("abc foo1 xyz", NULL), true);
215   ASSERT_EQ(s2.Match("abc bar2 xyz", NULL), false);
216 
217   // The moved-from object should have been reset and be reusable.
218   ASSERT_EQ(s1.Add("bar\\d+", NULL), 0);
219   ASSERT_EQ(s1.Compile(), true);
220   ASSERT_EQ(s1.Match("abc foo1 xyz", NULL), false);
221   ASSERT_EQ(s1.Match("abc bar2 xyz", NULL), true);
222 
223   // Verify that "overwriting" works and also doesn't leak memory.
224   // (The latter will need a leak detector such as LeakSanitizer.)
225   s1 = std::move(s2);
226   ASSERT_EQ(s1.Match("abc foo1 xyz", NULL), true);
227   ASSERT_EQ(s1.Match("abc bar2 xyz", NULL), false);
228 }
229 
230 }  // namespace re2
231