• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2008-2010, Google Inc.
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Neither the name of Google Inc. nor the names of its
11  * contributors may be used to endorse or promote products derived from
12  * this software without specific prior written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 // This file is part of ThreadSanitizer, a dynamic data race detector.
28 // Author: Evgeniy Stepanov.
29 
30 // This file contains tests for suppressions implementation.
31 
32 #include <gtest/gtest.h>
33 
34 #include "suppressions.h"
35 
36 #define VEC(arr) *(new vector<string>(arr, arr + sizeof(arr) / sizeof(*arr)))
37 
38 class BaseSuppressionsTest : public ::testing::Test {
39  protected:
IsSuppressed(string tool,string warning_type,const vector<string> & f_m,const vector<string> & f_d,const vector<string> & o)40   bool IsSuppressed(string tool, string warning_type, const vector<string>& f_m,
41       const vector<string>& f_d, const vector<string>& o) {
42     string result;
43     return supp_.StackTraceSuppressed(
44         tool, warning_type, f_m, f_d, o, &result);
45   }
46 
IsSuppressed(const vector<string> & f_m,const vector<string> & f_d,const vector<string> & o)47   bool IsSuppressed(const vector<string>& f_m, const vector<string>& f_d,
48       const vector<string>& o) {
49     return IsSuppressed("test_tool", "test_warning_type", f_m, f_d, o);
50   }
51 
52   Suppressions supp_;
53 };
54 
55 class SuppressionsTest : public BaseSuppressionsTest {
56  protected:
SetUp()57   virtual void SetUp() {
58     const string data =
59         "{\n"
60         "  name\n"
61         "  test_tool,tool2:test_warning_type\n"
62         "  fun:function1\n"
63         "  obj:object1\n"
64         "  fun:function2\n"
65         "}";
66     supp_.ReadFromString(data);
67   }
68 };
69 
70 
TEST_F(SuppressionsTest,Simple)71 TEST_F(SuppressionsTest, Simple) {
72   string m[] = {"aa", "bb", "cc"};
73   string d[] = {"aaa", "bbb", "ccc"};
74   string o[] = {"object1", "object2", "object3"};
75   ASSERT_FALSE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
76 }
77 
TEST_F(SuppressionsTest,Simple2)78 TEST_F(SuppressionsTest, Simple2) {
79   string m[] = {"function1", "bb", "function2"};
80   string d[] = {"aaa", "bbb", "ccc"};
81   string o[] = {"object2", "object1", "object3"};
82   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
83 }
84 
85 // A long stack trace is ok.
TEST_F(SuppressionsTest,LongTrace)86 TEST_F(SuppressionsTest, LongTrace) {
87   string m[] = {"function1", "bb", "function2", "zz"};
88   string d[] = {"aaa", "bbb", "ccc", "zzz"};
89   string o[] = {"object2", "object1", "object3", "o4"};
90   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
91 }
92 
93 // A stack trace template only matches at the top of the stack.
TEST_F(SuppressionsTest,OnlyMatchesAtTheTop)94 TEST_F(SuppressionsTest, OnlyMatchesAtTheTop) {
95   string m[] = {"zz", "function1", "bb", "function2"};
96   string d[] = {"zzz", "aaa", "bbb", "ccc"};
97   string o[] = {"o0", "object2", "object1", "object3"};
98   ASSERT_FALSE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
99 }
100 
101 // A short stack trace is not.
TEST_F(SuppressionsTest,ShortTrace)102 TEST_F(SuppressionsTest, ShortTrace) {
103   string m[] = {"function1", "bb"};
104   string d[] = {"aaa", "bbb"};
105   string o[] = {"object2", "object1"};
106   ASSERT_FALSE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
107 }
108 
109 class SuppressionsWithWildcardsTest : public BaseSuppressionsTest {
110  protected:
SetUp()111   virtual void SetUp() {
112     const string data =
113         "{\n"
114         "  name\n"
115         "  test_tool,tool2:test_warning_type\n"
116         "  fun:fun*1\n"
117         "  obj:obj*t1\n"
118         "  ...\n"
119         "  fun:f?n*2\n"
120         "}";
121     supp_.ReadFromString(data);
122   }
123 };
124 
TEST_F(SuppressionsWithWildcardsTest,Wildcards1)125 TEST_F(SuppressionsWithWildcardsTest, Wildcards1) {
126   string m[] = {"function1", "bb", "function2"};
127   string d[] = {"aaa", "bbb", "ccc"};
128   string o[] = {"object2", "object1", "object3"};
129   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
130 }
131 
TEST_F(SuppressionsWithWildcardsTest,Wildcards2)132 TEST_F(SuppressionsWithWildcardsTest, Wildcards2) {
133   string m[] = {"some_other_function1", "bb", "function2"};
134   string d[] = {"aaa", "bbb", "ccc"};
135   string o[] = {"object2", "object1", "object3"};
136   ASSERT_FALSE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
137 }
138 
TEST_F(SuppressionsWithWildcardsTest,Wildcards3)139 TEST_F(SuppressionsWithWildcardsTest, Wildcards3) {
140   string m[] = {"fun1", "bb", "fanction2"};
141   string d[] = {"aaa", "bbb", "ccc"};
142   string o[] = {"object2", "objt1", "object3"};
143   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
144 }
145 
146 // Tests "..." wildcard.
TEST_F(SuppressionsWithWildcardsTest,VerticalWildcards1)147 TEST_F(SuppressionsWithWildcardsTest, VerticalWildcards1) {
148   string m[] = {"fun1", "bb", "qq", "fanction2"};
149   string d[] = {"aaa", "bbb", "ddd", "ccc"};
150   string o[] = {"object2", "objt1", "object3", "object4"};
151   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
152 }
153 
154 
155 class MultipleStackTraceTest : public BaseSuppressionsTest {
156  protected:
SetUp()157   virtual void SetUp() {
158     const string data =
159         "{\n"
160         "  name\n"
161         "  test_tool,tool2:test_warning_type\n"
162         "  {\n"
163         "    fun:fun*1\n"
164         "  }\n"
165         "  {\n"
166         "    fun:fun*2\n"
167         "    fun:fun*3\n"
168         "  }\n"
169         "  {\n"
170         "    ...\n"
171         "    fun:fun*4\n"
172         "    obj:obj*5\n"
173         "  }\n"
174         "}";
175     supp_.ReadFromString(data);
176   }
177 };
178 
TEST_F(MultipleStackTraceTest,Simple1)179 TEST_F(MultipleStackTraceTest, Simple1) {
180   string m[] = {"fun1", "bb", "qq", "fun2"};
181   string d[] = {"aaa", "bbb", "ddd", "ccc"};
182   string o[] = {"object1", "object2", "object3", "object4"};
183   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
184 }
185 
TEST_F(MultipleStackTraceTest,SecondTemplateMatches)186 TEST_F(MultipleStackTraceTest, SecondTemplateMatches) {
187   string m[] = {"fun2", "fun3", "qq", "fun2"};
188   string d[] = {"aaa", "bbb", "ddd", "ccc"};
189   string o[] = {"object1", "object2", "object3", "object4"};
190   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
191 }
192 
TEST_F(MultipleStackTraceTest,ThirdTemplateMatches)193 TEST_F(MultipleStackTraceTest, ThirdTemplateMatches) {
194   string m[] = {"fun4", "bb", "qq", "fun2"};
195   string d[] = {"aaa", "bbb", "ddd", "ccc"};
196   string o[] = {"object1", "object5", "object3", "object4"};
197   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
198 }
199 
TEST_F(MultipleStackTraceTest,NothingMatches)200 TEST_F(MultipleStackTraceTest, NothingMatches) {
201   string m[] = {"_fun1", "bb", "qq", "fun2"};
202   string d[] = {"aaa", "bbb", "ddd", "ccc"};
203   string o[] = {"object1", "object2", "object3", "object4"};
204   ASSERT_FALSE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
205 }
206 
TEST_F(MultipleStackTraceTest,TwoTemplatesMatch)207 TEST_F(MultipleStackTraceTest, TwoTemplatesMatch) {
208   string m[] = {"fun1", "bb", "fun4", "fun2"};
209   string d[] = {"aaa", "bbb", "ddd", "ccc"};
210   string o[] = {"object1", "object2", "object3", "object5"};
211   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
212 }
213 
214 
TEST_F(BaseSuppressionsTest,StartsWithVerticalWildcard)215 TEST_F(BaseSuppressionsTest, StartsWithVerticalWildcard) {
216   const string data =
217       "{\n"
218       "  name\n"
219       "  test_tool:test_warning_type\n"
220       "  ...\n"
221       "  fun:qq\n"
222       "}";
223   ASSERT_GT(supp_.ReadFromString(data), 0);
224   string m[] = {"fun1", "bb", "qq", "function2"};
225   string d[] = {"aaa", "bbb", "ddd", "ccc"};
226   string o[] = {"object2", "objt1", "object3", "object4"};
227   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
228 }
229 
TEST_F(BaseSuppressionsTest,StartsWithVerticalWildcard2)230 TEST_F(BaseSuppressionsTest, StartsWithVerticalWildcard2) {
231   const string data =
232       "{\n"
233       "  name\n"
234       "  test_tool:test_warning_type\n"
235       "  ...\n"
236       "  fun:fun1\n"
237       "}";
238   ASSERT_GT(supp_.ReadFromString(data), 0);
239   string m[] = {"fun1", "bb", "qq", "function2"};
240   string d[] = {"aaa", "bbb", "ddd", "ccc"};
241   string o[] = {"object2", "objt1", "object3", "object4"};
242   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
243 }
244 
TEST_F(BaseSuppressionsTest,EndsWithVerticalWildcard)245 TEST_F(BaseSuppressionsTest, EndsWithVerticalWildcard) {
246   const string data =
247       "{\n"
248       "  name\n"
249       "  test_tool:test_warning_type\n"
250       "  fun:fun1\n"
251       "  ...\n"
252       "}";
253   ASSERT_GT(supp_.ReadFromString(data), 0);
254   string m[] = {"fun1", "bb", "qq", "function2"};
255   string d[] = {"aaa", "bbb", "ddd", "ccc"};
256   string o[] = {"object2", "objt1", "object3", "object4"};
257   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
258 }
259 
TEST_F(BaseSuppressionsTest,EndsWithVerticalWildcard2)260 TEST_F(BaseSuppressionsTest, EndsWithVerticalWildcard2) {
261   const string data =
262       "{\n"
263       "  name\n"
264       "  test_tool:test_warning_type\n"
265       "  fun:qq\n"
266       "  ...\n"
267       "}";
268   ASSERT_GT(supp_.ReadFromString(data), 0);
269   string m[] = {"fun1", "bb", "qq", "function2"};
270   string d[] = {"aaa", "bbb", "ddd", "ccc"};
271   string o[] = {"object2", "objt1", "object3", "object4"};
272   ASSERT_FALSE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
273 }
274 
TEST_F(BaseSuppressionsTest,Complex)275 TEST_F(BaseSuppressionsTest, Complex) {
276   const string data =
277       "{\n"
278       "  name\n"
279       "  test_tool:test_warning_type\n"
280       "  fun:qq\n"
281       "  ...\n"
282       "  obj:obj*3\n"
283       "  ...\n"
284       "  fun:function?\n"
285       "}";
286   ASSERT_GT(supp_.ReadFromString(data), 0);
287   string m[] = {"fun1", "bb", "qq", "function2"};
288   string d[] = {"aaa", "bbb", "ddd", "ccc"};
289   string o[] = {"object2", "objt1", "object3", "object4"};
290   ASSERT_FALSE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
291 }
292 
TEST_F(BaseSuppressionsTest,DemangledNames)293 TEST_F(BaseSuppressionsTest, DemangledNames) {
294   const string data =
295       "{\n"
296       "  name\n"
297       "  test_tool:test_warning_type\n"
298       "  fun:bb*w?\n"
299       "}";
300   ASSERT_GT(supp_.ReadFromString(data), 0);
301   string m[] = {"fun1", "bb", "qq", "function2"};
302   string d[] = {"bbbxxwz", "aaa", "ddd", "ccc"};
303   string o[] = {"object2", "objt1", "object3", "object4"};
304   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
305 }
306 
TEST_F(BaseSuppressionsTest,TrailingWhitespace)307 TEST_F(BaseSuppressionsTest, TrailingWhitespace) {
308   const string data =
309       "{\n"
310       "  name\n"
311       "  test_tool:test_warning_type\n"
312       "  fun:bb*w? \n"
313       "}";
314   ASSERT_GT(supp_.ReadFromString(data), 0);
315   string m[] = {"fun1", "bb", "qq", "function2"};
316   string d[] = {"bbbxxwz", "aaa", "ddd", "ccc"};
317   string o[] = {"object2", "objt1", "object3", "object4"};
318   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
319 }
320 
TEST_F(BaseSuppressionsTest,ObjectiveC)321 TEST_F(BaseSuppressionsTest, ObjectiveC) {
322   const string data =
323       "{\n"
324       "  name\n"
325       "  test_tool:test_warning_type\n"
326       "  fun:-[NSObject(NSKeyValueCoding) setValue:forKeyPath:]\n"
327       "}";
328   ASSERT_GT(supp_.ReadFromString(data), 0);
329   string m[] = {"-[NSObject(NSKeyValueCoding) setValue:forKeyPath:]", "function2"};
330   string d[] = {"bbbxxwz", "aaa", "ddd", "ccc"};
331   string o[] = {"object2", "objt1", "object3", "object4"};
332   ASSERT_TRUE(IsSuppressed(VEC(m), VEC(d), VEC(o)));
333 }
334 
335 
336 class FailingSuppressionsTest : public ::testing::Test {
337  protected:
ErrorLineNo(string data)338   int ErrorLineNo(string data) {
339     int result = supp_.ReadFromString(data);
340     if (result >= 0)
341       return -1;
342     else
343       return supp_.GetErrorLineNo();
344   }
345 
346   Suppressions supp_;
347 };
348 
TEST_F(FailingSuppressionsTest,NoOpeningBrace)349 TEST_F(FailingSuppressionsTest, NoOpeningBrace) {
350   const string data =
351       "  name\n"
352       "  test_tool:test_warning_type\n"
353       "  fun:bb*w? \n"
354       "}";
355   ASSERT_EQ(1, ErrorLineNo(data));
356 }
357 
TEST_F(FailingSuppressionsTest,Bad1)358 TEST_F(FailingSuppressionsTest, Bad1) {
359   const string data =
360       "{\n"
361       "  name\n"
362       "  something_else\n"
363       "  test_tool:test_warning_type\n"
364       "  fun:bb*w? \n"
365       "}";
366   ASSERT_EQ(3, ErrorLineNo(data));
367 }
368 
TEST_F(FailingSuppressionsTest,Bad2)369 TEST_F(FailingSuppressionsTest, Bad2) {
370   const string data =
371       "{\n"
372       "  name\n"
373       "  test_tool:test_warning_type\n"
374       "  extra\n"
375       "  fun:bb*w? \n"
376       "}";
377   ASSERT_EQ(4, ErrorLineNo(data));
378 }
379 
TEST_F(FailingSuppressionsTest,Bad3)380 TEST_F(FailingSuppressionsTest, Bad3) {
381   const string data =
382       "{\n"
383       "  name\n"
384       "  test_tool:test_warning_type\n"
385       "  fun:bb*w? \n"
386       "  extra\n"
387       "}";
388   ASSERT_EQ(5, ErrorLineNo(data));
389 }
390 
TEST_F(FailingSuppressionsTest,SomeWeirdTextAfterASuppression)391 TEST_F(FailingSuppressionsTest, SomeWeirdTextAfterASuppression) {
392   const string data =
393       "{\n"
394       "  name\n"
395       "  test_tool:test_warning_type\n"
396       "  fun:bb*w? \n"
397       "}\n"
398       "some_weird_text\n"
399       "after_a_suppression\n";
400   ASSERT_EQ(6, ErrorLineNo(data));
401 }
402 
TEST_F(FailingSuppressionsTest,NoToolsLineInMultitraceSuppression)403 TEST_F(FailingSuppressionsTest, NoToolsLineInMultitraceSuppression) {
404   const string data =
405       "{\n"
406       "  name\n"
407       "  {\n"
408       "    fun:fun*2\n"
409       "    fun:fun*3\n"
410       "  }\n"
411       "  {\n"
412       "    ...\n"
413       "    fun:fun*4\n"
414       "    obj:obj*5\n"
415       "  }\n"
416       "}";
417   ASSERT_EQ(3, ErrorLineNo(data));
418 }
419 
TEST_F(FailingSuppressionsTest,BadStacktrace1)420 TEST_F(FailingSuppressionsTest, BadStacktrace1) {
421   const string data =
422       "{\n"
423       "  name\n"
424       "  test_tool:test_warning_type\n"
425       "  {\n"
426       "    fun:fun*2\n"
427       "    fun:fun*3\n"
428       "  }\n"
429       "  {\n"
430       "    zzz\n"
431       "    fun:fun*4\n"
432       "    obj:obj*5\n"
433       "  }\n"
434       "}";
435   ASSERT_EQ(9, ErrorLineNo(data));
436 }
437 
TEST_F(FailingSuppressionsTest,BadStacktrace2)438 TEST_F(FailingSuppressionsTest, BadStacktrace2) {
439   const string data =
440       "{\n"
441       "  name\n"
442       "  test_tool:test_warning_type\n"
443       "  {\n"
444       "    fun:fun*2\n"
445       "    fun:fun*3\n"
446       "  }\n"
447       "  {\n"
448       "    {\n"
449       "    fun:fun*4\n"
450       "    obj:obj*5\n"
451       "  }\n"
452       "}";
453   ASSERT_EQ(9, ErrorLineNo(data));
454 }
455 
TEST_F(FailingSuppressionsTest,BadStacktrace3)456 TEST_F(FailingSuppressionsTest, BadStacktrace3) {
457   const string data =
458       "{\n"
459       "  name\n"
460       "  test_tool:test_warning_type\n"
461       "  {\n"
462       "    fun:fun*2\n"
463       "    fun:fun*3\n"
464       "  }\n"
465       "  {\n"
466       "    fun:fun*4\n"
467       "    obj:obj*5\n"
468       "  }\n"
469       "  zzz\n"
470       "}";
471   ASSERT_EQ(12, ErrorLineNo(data));
472 }
473 
TEST_F(FailingSuppressionsTest,StacktraceWithParenthesis)474 TEST_F(FailingSuppressionsTest, StacktraceWithParenthesis) {
475   const string data =
476       "{\n"
477       "  name\n"
478       "  test_tool:test_warning_type\n"
479       "  {\n"
480       "    fun:fun*2\n"
481       "    fun:fun*3\n"
482       "  }\n"
483       "  {\n"
484       "    fun:fun*4()\n"
485       "    obj:obj*5\n"
486       "  }\n"
487       "}";
488   ASSERT_EQ(9, ErrorLineNo(data));
489 }
490 
TEST_F(FailingSuppressionsTest,StacktraceWithAngleBraces)491 TEST_F(FailingSuppressionsTest, StacktraceWithAngleBraces) {
492   const string data =
493       "{\n"
494       "  name\n"
495       "  test_tool:test_warning_type\n"
496       "  {\n"
497       "    fun:fun*2\n"
498       "    fun:fun*3\n"
499       "  }\n"
500       "  {\n"
501       "    fun:fun<int>*4\n"
502       "    obj:obj*5\n"
503       "  }\n"
504       "}";
505   ASSERT_EQ(9, ErrorLineNo(data));
506 }
507 
508 
TEST(WildcardTest,Simple)509 TEST(WildcardTest, Simple) {
510   EXPECT_TRUE(StringMatch("abc", "abc"));
511   EXPECT_FALSE(StringMatch("abcd", "abc"));
512   EXPECT_FALSE(StringMatch("dabc", "abc"));
513   EXPECT_FALSE(StringMatch("ab", "abc"));
514   EXPECT_FALSE(StringMatch("", "abc"));
515   EXPECT_FALSE(StringMatch("abc", ""));
516   EXPECT_TRUE(StringMatch("", ""));
517 }
518 
TEST(WildcardTest,SingleCharacterWildcard)519 TEST(WildcardTest, SingleCharacterWildcard) {
520   EXPECT_TRUE(StringMatch("a?c", "abc"));
521   EXPECT_TRUE(StringMatch("?bc", "abc"));
522   EXPECT_TRUE(StringMatch("ab?", "abc"));
523   EXPECT_TRUE(StringMatch("a??", "abc"));
524   EXPECT_TRUE(StringMatch("???", "abc"));
525   EXPECT_TRUE(StringMatch("?", "a"));
526   EXPECT_FALSE(StringMatch("?zc", "abc"));
527   EXPECT_FALSE(StringMatch("?bz", "abc"));
528   EXPECT_FALSE(StringMatch("b?c", "abc"));
529   EXPECT_FALSE(StringMatch("az?", "abc"));
530   EXPECT_FALSE(StringMatch("abc?", "abc"));
531   EXPECT_FALSE(StringMatch("?abc", "abc"));
532   EXPECT_FALSE(StringMatch("?", ""));
533   EXPECT_FALSE(StringMatch("??", ""));
534 }
535 
TEST(WildcardTest,MultiCharacterWildcard)536 TEST(WildcardTest, MultiCharacterWildcard) {
537   EXPECT_TRUE(StringMatch("*x", "x"));
538   EXPECT_TRUE(StringMatch("x*", "x"));
539   EXPECT_TRUE(StringMatch("*x*", "x"));
540 
541   EXPECT_TRUE(StringMatch("a*d", "abcd"));
542   EXPECT_TRUE(StringMatch("ab*d", "abcd"));
543   EXPECT_TRUE(StringMatch("*cd", "abcd"));
544   EXPECT_TRUE(StringMatch("*d", "abcd"));
545   EXPECT_TRUE(StringMatch("ab*", "abcd"));
546   EXPECT_TRUE(StringMatch("a*", "abcd"));
547   EXPECT_TRUE(StringMatch("*", "abcd"));
548   EXPECT_TRUE(StringMatch("ab*cd", "abcd"));
549 
550   EXPECT_TRUE(StringMatch("ab**", "abcd"));
551   EXPECT_TRUE(StringMatch("**", "abcd"));
552   EXPECT_TRUE(StringMatch("***", "abcd"));
553   EXPECT_TRUE(StringMatch("**d", "abcd"));
554   EXPECT_TRUE(StringMatch("*c*", "abcd"));
555   EXPECT_TRUE(StringMatch("a*c*d*f", "abcdef"));
556   EXPECT_TRUE(StringMatch("a*c*e*", "abcdef"));
557   EXPECT_TRUE(StringMatch("*a*b*f", "abcdef"));
558   EXPECT_TRUE(StringMatch("*b*d*", "abcdef"));
559 
560   EXPECT_FALSE(StringMatch("b*", "abcd"));
561   EXPECT_FALSE(StringMatch("*c", "abcd"));
562   EXPECT_FALSE(StringMatch("*a", "abcd"));
563 }
564 
TEST(WildcardTest,WildcardCharactersInText)565 TEST(WildcardTest, WildcardCharactersInText) {
566   EXPECT_TRUE(StringMatch("?", "?"));
567   EXPECT_FALSE(StringMatch("a", "?"));
568   EXPECT_FALSE(StringMatch("ab", "a?"));
569   EXPECT_FALSE(StringMatch("ab", "?b"));
570   EXPECT_TRUE(StringMatch("a?", "a?"));
571   EXPECT_TRUE(StringMatch("?b", "?b"));
572 
573   EXPECT_TRUE(StringMatch("*", "*"));
574   EXPECT_FALSE(StringMatch("a", "*"));
575   EXPECT_FALSE(StringMatch("ab", "a*"));
576   EXPECT_FALSE(StringMatch("ab", "*b"));
577   EXPECT_TRUE(StringMatch("a*", "a*"));
578   EXPECT_TRUE(StringMatch("*b", "*b"));
579 }
580 
main(int argc,char ** argv)581 int main(int argc, char **argv) {
582   testing::InitGoogleTest(&argc, argv);
583 
584   return RUN_ALL_TESTS();
585 }
586