5#include "gtest/gtest.h"
7static const char*
kEntry = R
"entry(google
8Copyright \(c\) \d+ Google Inc
9Copyright \(c\) \d+ Google Inc. All rights reserved.
11Redistribution and use in source and binary forms, with or without
12modification, are permitted provided that the following conditions are
15 \* Redistributions of source code must retain the above copyright
16 notice, this list of conditions and the following disclaimer.
18 \* Redistributions in binary form must reproduce the above copyright
19 notice, this list of conditions and the following disclaimer in
20 the documentation and/or other materials provided with the
23 \* Neither the name of the copyright holder nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without specific prior written permission.
27THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \(INCLUDING, BUT NOT
33LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34DATA, OR PROFITS; OR BUSINESS INTERRUPTION\) HOWEVER CAUSED AND ON ANY
35THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36\(INCLUDING NEGLIGENCE OR OTHERWISE\) ARISING IN ANY WAY OUT OF THE USE
37OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 R
"entry(Copyright (c) 2011 Google Inc. All rights reserved.
43Redistribution and use in source and binary forms, with or without
44modification, are permitted provided that the following conditions are
47 * Redistributions of source code must retain the above copyright
48 notice, this list of conditions and the following disclaimer.
50 * Redistributions in binary form must reproduce the above copyright
51 notice, this list of conditions and the following disclaimer in
52 the documentation and/or other materials provided with the
55 * Neither the name of the copyright holder nor the names of its
56 contributors may be used to endorse or promote products derived
57 from this software without specific prior written permission.
59THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
60"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
61LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
62A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
63OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
64SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
65LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
66DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
67THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
68(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
69OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73 absl::StatusOr<Catalog> catalog =
75 ASSERT_TRUE(catalog.ok());
76 absl::StatusOr<std::vector<Catalog::Match>> match = catalog->FindMatch(
"foo");
77 ASSERT_TRUE(match.ok());
78 ASSERT_EQ(match->front().GetMatcher(),
"foobar");
81TEST(CatalogTest, MultipleMatchOverlapping) {
83 {{
"matcher1",
".*foo.*",
".*foo.*"}, {
"matcher2",
".*oo.*",
".*oo.*"}});
84 ASSERT_TRUE(catalog.ok()) << catalog.status();
85 absl::StatusOr<std::vector<Catalog::Match>> has_match =
86 catalog->FindMatch(
"foo");
87 ASSERT_FALSE(has_match.ok());
88 ASSERT_TRUE(RE2::PartialMatch(has_match.status().message(),
89 "Selected matchers overlap"))
90 << has_match.status().message();
91 ASSERT_TRUE(RE2::PartialMatch(has_match.status().message(),
"matcher1"))
92 << has_match.status().message();
93 ASSERT_TRUE(RE2::PartialMatch(has_match.status().message(),
"matcher2"))
94 << has_match.status().message();
97TEST(CatalogTest, MultipleSelectorsFail) {
99 {{
"matcher1",
".*foo.*",
"blah"}, {
"matcher2",
".*oo.*",
"blah"}});
100 ASSERT_TRUE(catalog.ok()) << catalog.status();
101 absl::StatusOr<std::vector<Catalog::Match>> has_match =
102 catalog->FindMatch(
"foo");
103 ASSERT_FALSE(has_match.ok());
104 ASSERT_TRUE(RE2::PartialMatch(has_match.status().message(),
"matcher1"))
105 << has_match.status().message();
106 ASSERT_TRUE(RE2::PartialMatch(has_match.status().message(),
"matcher2"))
107 << has_match.status().message();
110TEST(CatalogTest, OnlyOneSelectorsFail) {
112 {{
"matcher1",
".*foo.*",
".*foo.*"}, {
"matcher2",
".*oo.*",
"blah"}});
113 ASSERT_TRUE(catalog.ok()) << catalog.status();
114 absl::StatusOr<std::vector<Catalog::Match>> has_match =
115 catalog->FindMatch(
"foo");
116 ASSERT_FALSE(has_match.ok());
117 ASSERT_TRUE(RE2::PartialMatch(has_match.status().message(),
"matcher1"))
118 << has_match.status().message();
119 ASSERT_TRUE(RE2::PartialMatch(has_match.status().message(),
"matcher2"))
120 << has_match.status().message();
123TEST(CatalogTest, MultipleMatchNoOverlap) {
124 absl::StatusOr<Catalog> catalog =
125 Catalog::Make({{
"foo",
".*foo",
".*foo"}, {
"bar",
"bar.*",
"bar.*"}});
126 ASSERT_TRUE(catalog.ok()) << catalog.status();
127 absl::StatusOr<std::vector<Catalog::Match>> has_match =
128 catalog->FindMatch(
"hello foo bar world");
129 ASSERT_TRUE(has_match.ok()) << has_match.status();
132TEST(CatalogTest, NoSelectorMatch) {
133 absl::StatusOr<Catalog> catalog =
135 ASSERT_TRUE(catalog.ok());
136 absl::StatusOr<std::vector<Catalog::Match>> match = catalog->FindMatch(
"foo");
137 ASSERT_FALSE(match.ok());
138 ASSERT_EQ(match.status().code(), absl::StatusCode::kNotFound);
141TEST(CatalogTest, NoSelectionMatch) {
142 absl::StatusOr<Catalog> catalog =
144 ASSERT_TRUE(catalog.ok());
145 absl::StatusOr<std::vector<Catalog::Match>> match = catalog->FindMatch(
"foo");
146 ASSERT_FALSE(match.ok());
147 ASSERT_EQ(match.status().code(), absl::StatusCode::kNotFound);
150TEST(CatalogTest, SimpleParseEntry) {
151 std::stringstream ss;
154 ss << R
"match(Multiline
159 EXPECT_TRUE(entry.ok()) << entry.status();
161 EXPECT_EQ(entry->name,
"foobar");
162 EXPECT_EQ(entry->unique,
"unique");
163 EXPECT_EQ(entry->matcher, R
"match(Multiline\s+matcher\s+.*)match");
167TEST(CatalogTest, SkiaLicense) {
168 std::stringstream ss;
171 ASSERT_TRUE(entry.ok()) << entry.status();
173 ASSERT_TRUE(catalog.ok());
174 absl::StatusOr<std::vector<Catalog::Match>> match =
176 EXPECT_TRUE(match.ok()) << match.status();
180std::string RemoveNewlines(std::string_view
input) {
182 return std::string();
184 std::string no_newline;
185 char last_char =
input[0];
186 for (
size_t i = 1;
i <
input.size(); ++
i) {
188 if (last_char ==
'\n' && current ==
'\n') {
189 no_newline.push_back(
'\n');
190 no_newline.push_back(
'\n');
191 }
else if (last_char ==
'\n') {
192 no_newline.push_back(
' ');
194 no_newline.push_back(last_char);
198 if (last_char !=
'\n') {
199 no_newline.push_back(last_char);
205TEST(CatalogTest, SkiaLicenseIgnoreWhitespace) {
206 std::stringstream ss;
209 ASSERT_TRUE(entry.ok()) << entry.status();
211 ASSERT_TRUE(catalog.ok());
213 std::string no_newline_license = RemoveNewlines(
kSkiaLicense);
215 absl::StatusOr<std::vector<Catalog::Match>> match =
216 catalog->FindMatch(no_newline_license);
217 ASSERT_TRUE(match.ok()) << match.status();
218 ASSERT_EQ(match->size(), 1u);
219 EXPECT_EQ(match->at(0).GetMatchedText(), no_newline_license);
222TEST(CatalogTest, SkiaLicenseIgnoreTrailing) {
223 std::stringstream ss;
226 ASSERT_TRUE(entry.ok()) << entry.status();
228 ASSERT_TRUE(catalog.ok());
231 ASSERT_EQ(no_end.back(),
'\n');
234 absl::StatusOr<std::vector<Catalog::Match>> match =
235 catalog->FindMatch(no_end);
236 EXPECT_TRUE(match.ok()) << match.status();
239TEST(CatalogTest, ExtractsGroups) {
240 std::string entry_text = R
"entry(entry
244 std::stringstream ss;
247 ASSERT_TRUE(entry.ok()) << entry.status();
249 ASSERT_TRUE(catalog.ok());
251 std::string text = "start hello stop world last";
253 absl::StatusOr<std::vector<Catalog::Match>> match = catalog->FindMatch(
text);
254 EXPECT_TRUE(match.ok()) << match.status();
255 ASSERT_EQ(match->size(), 1u);
256 EXPECT_EQ(match->at(0).GetMatchedText(),
"startstoplast");
259TEST(CatalogTest, OptionalGroups) {
260 std::string entry_text = R
"entry(entry
261start.*middle(?:foo)?end
262start(.*)middle(?:(foo))?end
264 std::stringstream ss;
267 ASSERT_TRUE(entry.ok()) << entry.status();
269 ASSERT_TRUE(catalog.ok());
271 std::string text = "start hello middleend";
272 absl::StatusOr<std::vector<Catalog::Match>> match = catalog->FindMatch(
text);
273 EXPECT_TRUE(match.ok()) << match.status();
274 ASSERT_EQ(match->size(), 1u);
275 EXPECT_EQ(match->at(0).GetMatchedText(),
"startmiddleend");
TEST(CatalogTest, Simple)
static const char * kEntry
static const char * kSkiaLicense
static absl::StatusOr< Entry > ParseEntry(std::istream &is)
VisibleForTesting.
static absl::StatusOr< Catalog > Make(const std::vector< Entry > &entries)
Make a Catalog for testing.