Home | History | Annotate | Download | only in url_matcher
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "components/url_matcher/url_matcher.h"
      6 
      7 #include "base/strings/string_util.h"
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 #include "url/gurl.h"
     10 
     11 namespace url_matcher {
     12 
     13 //
     14 // URLMatcherCondition
     15 //
     16 
     17 TEST(URLMatcherConditionTest, Constructors) {
     18   StringPattern pattern("example.com", 1);
     19   URLMatcherCondition m1(URLMatcherCondition::HOST_SUFFIX, &pattern);
     20   EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX, m1.criterion());
     21   EXPECT_EQ(&pattern, m1.string_pattern());
     22 
     23   URLMatcherCondition m2;
     24   m2 = m1;
     25   EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX, m2.criterion());
     26   EXPECT_EQ(&pattern, m2.string_pattern());
     27 
     28   URLMatcherCondition m3(m1);
     29   EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX, m3.criterion());
     30   EXPECT_EQ(&pattern, m3.string_pattern());
     31 }
     32 
     33 TEST(URLMatcherSchemeFilter, TestMatching) {
     34   URLMatcherSchemeFilter filter1("https");
     35   std::vector<std::string> filter2_content;
     36   filter2_content.push_back("http");
     37   filter2_content.push_back("https");
     38   URLMatcherSchemeFilter filter2(filter2_content);
     39 
     40   GURL matching_url("https://www.foobar.com");
     41   GURL non_matching_url("http://www.foobar.com");
     42   EXPECT_TRUE(filter1.IsMatch(matching_url));
     43   EXPECT_FALSE(filter1.IsMatch(non_matching_url));
     44   EXPECT_TRUE(filter2.IsMatch(matching_url));
     45   EXPECT_TRUE(filter2.IsMatch(non_matching_url));
     46 }
     47 
     48 TEST(URLMatcherPortFilter, TestMatching) {
     49   std::vector<URLMatcherPortFilter::Range> ranges;
     50   ranges.push_back(URLMatcherPortFilter::CreateRange(80, 90));
     51   ranges.push_back(URLMatcherPortFilter::CreateRange(8080));
     52   URLMatcherPortFilter filter(ranges);
     53   EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com")));
     54   EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com:80")));
     55   EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com:81")));
     56   EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com:90")));
     57   EXPECT_TRUE(filter.IsMatch(GURL("http://www.example.com:8080")));
     58   EXPECT_FALSE(filter.IsMatch(GURL("http://www.example.com:79")));
     59   EXPECT_FALSE(filter.IsMatch(GURL("http://www.example.com:91")));
     60   EXPECT_FALSE(filter.IsMatch(GURL("https://www.example.com")));
     61 }
     62 
     63 TEST(URLMatcherConditionTest, IsFullURLCondition) {
     64   StringPattern pattern("example.com", 1);
     65   EXPECT_FALSE(URLMatcherCondition(URLMatcherCondition::HOST_SUFFIX,
     66       &pattern).IsFullURLCondition());
     67 
     68   EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::HOST_CONTAINS,
     69       &pattern).IsFullURLCondition());
     70   EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::PATH_CONTAINS,
     71       &pattern).IsFullURLCondition());
     72   EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::QUERY_CONTAINS,
     73       &pattern).IsFullURLCondition());
     74 
     75   EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_PREFIX,
     76       &pattern).IsFullURLCondition());
     77   EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_SUFFIX,
     78       &pattern).IsFullURLCondition());
     79   EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_CONTAINS,
     80       &pattern).IsFullURLCondition());
     81   EXPECT_TRUE(URLMatcherCondition(URLMatcherCondition::URL_EQUALS,
     82       &pattern).IsFullURLCondition());
     83 }
     84 
     85 TEST(URLMatcherConditionTest, IsMatch) {
     86   GURL url1("http://www.example.com/www.foobar.com/index.html");
     87   GURL url2("http://www.foobar.com/example.com/index.html");
     88 
     89   StringPattern pattern("example.com", 1);
     90   URLMatcherCondition m1(URLMatcherCondition::HOST_SUFFIX, &pattern);
     91 
     92   std::set<StringPattern::ID> matching_patterns;
     93 
     94   // matches = {0} --> matcher did not indicate that m1 was a match.
     95   matching_patterns.insert(0);
     96   EXPECT_FALSE(m1.IsMatch(matching_patterns, url1));
     97 
     98   // matches = {0, 1} --> matcher did indicate that m1 was a match.
     99   matching_patterns.insert(1);
    100   EXPECT_TRUE(m1.IsMatch(matching_patterns, url1));
    101 
    102   // For m2 we use a HOST_CONTAINS test, which requires a post-validation
    103   // whether the match reported by the SubstringSetMatcher occurs really
    104   // in the correct url component.
    105   URLMatcherCondition m2(URLMatcherCondition::HOST_CONTAINS, &pattern);
    106   EXPECT_TRUE(m2.IsMatch(matching_patterns, url1));
    107   EXPECT_FALSE(m2.IsMatch(matching_patterns, url2));
    108 }
    109 
    110 TEST(URLMatcherConditionTest, Comparison) {
    111   StringPattern p1("foobar.com", 1);
    112   StringPattern p2("foobar.com", 2);
    113   // The first component of each test is expected to be < than the second.
    114   URLMatcherCondition test_smaller[][2] = {
    115       {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1),
    116        URLMatcherCondition(URLMatcherCondition::HOST_SUFFIX, &p1)},
    117       {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1),
    118        URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p2)},
    119       {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, NULL),
    120        URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p2)},
    121       {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1),
    122        URLMatcherCondition(URLMatcherCondition::HOST_SUFFIX, NULL)},
    123   };
    124   for (size_t i = 0; i < arraysize(test_smaller); ++i) {
    125     EXPECT_TRUE(test_smaller[i][0] < test_smaller[i][1])
    126         << "Test " << i << " of test_smaller failed";
    127     EXPECT_FALSE(test_smaller[i][1] < test_smaller[i][0])
    128         << "Test " << i << " of test_smaller failed";
    129   }
    130   URLMatcherCondition test_equal[][2] = {
    131       {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1),
    132        URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, &p1)},
    133       {URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, NULL),
    134        URLMatcherCondition(URLMatcherCondition::HOST_PREFIX, NULL)},
    135   };
    136   for (size_t i = 0; i < arraysize(test_equal); ++i) {
    137     EXPECT_FALSE(test_equal[i][0] < test_equal[i][1])
    138         << "Test " << i << " of test_equal failed";
    139     EXPECT_FALSE(test_equal[i][1] < test_equal[i][0])
    140         << "Test " << i << " of test_equal failed";
    141   }
    142 }
    143 
    144 //
    145 // URLMatcherConditionFactory
    146 //
    147 
    148 namespace {
    149 
    150 bool Matches(const URLMatcherCondition& condition, std::string text) {
    151   return text.find(condition.string_pattern()->pattern()) !=
    152       std::string::npos;
    153 }
    154 
    155 }  // namespace
    156 
    157 TEST(URLMatcherConditionFactoryTest, GURLCharacterSet) {
    158   // GURL guarantees that neither domain, nor path, nor query may contain
    159   // non ASCII-7 characters. We test this here, because a change to this
    160   // guarantee breaks this implementation horribly.
    161   GURL url("http://www.f.com/f?f#f");
    162   EXPECT_TRUE(base::IsStringASCII(url.host()));
    163   EXPECT_TRUE(base::IsStringASCII(url.path()));
    164   EXPECT_TRUE(base::IsStringASCII(url.query()));
    165   EXPECT_FALSE(base::IsStringASCII(url.ref()));
    166 }
    167 
    168 TEST(URLMatcherConditionFactoryTest, Criteria) {
    169   URLMatcherConditionFactory factory;
    170   EXPECT_EQ(URLMatcherCondition::HOST_PREFIX,
    171             factory.CreateHostPrefixCondition("foo").criterion());
    172   EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX,
    173             factory.CreateHostSuffixCondition("foo").criterion());
    174   EXPECT_EQ(URLMatcherCondition::HOST_CONTAINS,
    175             factory.CreateHostContainsCondition("foo").criterion());
    176   EXPECT_EQ(URLMatcherCondition::HOST_EQUALS,
    177             factory.CreateHostEqualsCondition("foo").criterion());
    178   EXPECT_EQ(URLMatcherCondition::PATH_PREFIX,
    179             factory.CreatePathPrefixCondition("foo").criterion());
    180   EXPECT_EQ(URLMatcherCondition::PATH_SUFFIX,
    181             factory.CreatePathSuffixCondition("foo").criterion());
    182   EXPECT_EQ(URLMatcherCondition::PATH_CONTAINS,
    183             factory.CreatePathContainsCondition("foo").criterion());
    184   EXPECT_EQ(URLMatcherCondition::PATH_EQUALS,
    185             factory.CreatePathEqualsCondition("foo").criterion());
    186   EXPECT_EQ(URLMatcherCondition::QUERY_PREFIX,
    187             factory.CreateQueryPrefixCondition("foo").criterion());
    188   EXPECT_EQ(URLMatcherCondition::QUERY_SUFFIX,
    189             factory.CreateQuerySuffixCondition("foo").criterion());
    190   EXPECT_EQ(URLMatcherCondition::QUERY_CONTAINS,
    191             factory.CreateQueryContainsCondition("foo").criterion());
    192   EXPECT_EQ(URLMatcherCondition::QUERY_EQUALS,
    193             factory.CreateQueryEqualsCondition("foo").criterion());
    194   EXPECT_EQ(URLMatcherCondition::HOST_SUFFIX_PATH_PREFIX,
    195             factory.CreateHostSuffixPathPrefixCondition("foo",
    196                                                         "bar").criterion());
    197   EXPECT_EQ(URLMatcherCondition::HOST_EQUALS_PATH_PREFIX,
    198             factory.CreateHostEqualsPathPrefixCondition("foo",
    199                                                         "bar").criterion());
    200   EXPECT_EQ(URLMatcherCondition::URL_PREFIX,
    201             factory.CreateURLPrefixCondition("foo").criterion());
    202   EXPECT_EQ(URLMatcherCondition::URL_SUFFIX,
    203             factory.CreateURLSuffixCondition("foo").criterion());
    204   EXPECT_EQ(URLMatcherCondition::URL_CONTAINS,
    205             factory.CreateURLContainsCondition("foo").criterion());
    206   EXPECT_EQ(URLMatcherCondition::URL_EQUALS,
    207             factory.CreateURLEqualsCondition("foo").criterion());
    208   EXPECT_EQ(URLMatcherCondition::URL_MATCHES,
    209             factory.CreateURLMatchesCondition("foo").criterion());
    210 }
    211 
    212 TEST(URLMatcherConditionFactoryTest, TestSingletonProperty) {
    213   URLMatcherConditionFactory factory;
    214   URLMatcherCondition c1 = factory.CreateHostEqualsCondition("www.google.com");
    215   URLMatcherCondition c2 = factory.CreateHostEqualsCondition("www.google.com");
    216   EXPECT_EQ(c1.criterion(), c2.criterion());
    217   EXPECT_EQ(c1.string_pattern(), c2.string_pattern());
    218   URLMatcherCondition c3 = factory.CreateHostEqualsCondition("www.google.de");
    219   EXPECT_EQ(c2.criterion(), c3.criterion());
    220   EXPECT_NE(c2.string_pattern(), c3.string_pattern());
    221   EXPECT_NE(c2.string_pattern()->id(), c3.string_pattern()->id());
    222   EXPECT_NE(c2.string_pattern()->pattern(),
    223             c3.string_pattern()->pattern());
    224   URLMatcherCondition c4 = factory.CreateURLMatchesCondition("www.google.com");
    225   URLMatcherCondition c5 = factory.CreateURLContainsCondition("www.google.com");
    226   // Regex patterns and substring patterns do not share IDs.
    227   EXPECT_EQ(c5.string_pattern()->pattern(), c4.string_pattern()->pattern());
    228   EXPECT_NE(c5.string_pattern(), c4.string_pattern());
    229   EXPECT_NE(c5.string_pattern()->id(), c4.string_pattern()->id());
    230 
    231   // Check that all StringPattern singletons are freed if we call
    232   // ForgetUnusedPatterns.
    233   StringPattern::ID old_id_1 = c1.string_pattern()->id();
    234   StringPattern::ID old_id_4 = c4.string_pattern()->id();
    235   factory.ForgetUnusedPatterns(std::set<StringPattern::ID>());
    236   EXPECT_TRUE(factory.IsEmpty());
    237   URLMatcherCondition c6 = factory.CreateHostEqualsCondition("www.google.com");
    238   EXPECT_NE(old_id_1, c6.string_pattern()->id());
    239   URLMatcherCondition c7 = factory.CreateURLMatchesCondition("www.google.com");
    240   EXPECT_NE(old_id_4, c7.string_pattern()->id());
    241 }
    242 
    243 TEST(URLMatcherConditionFactoryTest, TestComponentSearches) {
    244   GURL gurl("https://www.google.com:1234/webhp?sourceid=chrome-instant&ie=UTF-8"
    245       "&ion=1#hl=en&output=search&sclient=psy-ab&q=chrome%20is%20awesome");
    246   URLMatcherConditionFactory factory;
    247   std::string url = factory.CanonicalizeURLForComponentSearches(gurl);
    248 
    249   // Test host component.
    250   EXPECT_TRUE(Matches(factory.CreateHostPrefixCondition(std::string()), url));
    251   EXPECT_TRUE(Matches(factory.CreateHostPrefixCondition("www.goog"), url));
    252   EXPECT_TRUE(
    253       Matches(factory.CreateHostPrefixCondition("www.google.com"), url));
    254   EXPECT_TRUE(
    255       Matches(factory.CreateHostPrefixCondition(".www.google.com"), url));
    256   EXPECT_FALSE(Matches(factory.CreateHostPrefixCondition("google.com"), url));
    257   EXPECT_FALSE(
    258       Matches(factory.CreateHostPrefixCondition("www.google.com/"), url));
    259   EXPECT_FALSE(Matches(factory.CreateHostPrefixCondition("webhp"), url));
    260 
    261   EXPECT_TRUE(Matches(factory.CreateHostSuffixCondition(std::string()), url));
    262   EXPECT_TRUE(Matches(factory.CreateHostSuffixCondition("com"), url));
    263   EXPECT_TRUE(Matches(factory.CreateHostSuffixCondition(".com"), url));
    264   EXPECT_TRUE(
    265       Matches(factory.CreateHostSuffixCondition("www.google.com"), url));
    266   EXPECT_TRUE(
    267       Matches(factory.CreateHostSuffixCondition(".www.google.com"), url));
    268   EXPECT_FALSE(Matches(factory.CreateHostSuffixCondition("www"), url));
    269   EXPECT_FALSE(
    270       Matches(factory.CreateHostSuffixCondition("www.google.com/"), url));
    271   EXPECT_FALSE(Matches(factory.CreateHostSuffixCondition("webhp"), url));
    272 
    273   EXPECT_FALSE(Matches(factory.CreateHostEqualsCondition(std::string()), url));
    274   EXPECT_FALSE(Matches(factory.CreateHostEqualsCondition("www"), url));
    275   EXPECT_TRUE(
    276       Matches(factory.CreateHostEqualsCondition("www.google.com"), url));
    277   EXPECT_FALSE(
    278       Matches(factory.CreateHostEqualsCondition("www.google.com/"), url));
    279 
    280 
    281   // Test path component.
    282   EXPECT_TRUE(Matches(factory.CreatePathPrefixCondition(std::string()), url));
    283   EXPECT_TRUE(Matches(factory.CreatePathPrefixCondition("/web"), url));
    284   EXPECT_TRUE(Matches(factory.CreatePathPrefixCondition("/webhp"), url));
    285   EXPECT_FALSE(Matches(factory.CreatePathPrefixCondition("webhp"), url));
    286   EXPECT_FALSE(Matches(factory.CreatePathPrefixCondition("/webhp?"), url));
    287   EXPECT_FALSE(Matches(factory.CreatePathPrefixCondition("?sourceid"), url));
    288 
    289   EXPECT_TRUE(Matches(factory.CreatePathSuffixCondition(std::string()), url));
    290   EXPECT_TRUE(Matches(factory.CreatePathSuffixCondition("webhp"), url));
    291   EXPECT_TRUE(Matches(factory.CreatePathSuffixCondition("/webhp"), url));
    292   EXPECT_FALSE(Matches(factory.CreatePathSuffixCondition("/web"), url));
    293   EXPECT_FALSE(Matches(factory.CreatePathSuffixCondition("/webhp?"), url));
    294 
    295   EXPECT_TRUE(Matches(factory.CreatePathEqualsCondition("/webhp"), url));
    296   EXPECT_FALSE(Matches(factory.CreatePathEqualsCondition("webhp"), url));
    297   EXPECT_FALSE(Matches(factory.CreatePathEqualsCondition("/webhp?"), url));
    298   EXPECT_FALSE(
    299       Matches(factory.CreatePathEqualsCondition("www.google.com"), url));
    300 
    301 
    302   // Test query component.
    303   EXPECT_TRUE(Matches(factory.CreateQueryPrefixCondition(std::string()), url));
    304   EXPECT_TRUE(Matches(factory.CreateQueryPrefixCondition("sourceid"), url));
    305   // The '?' at the beginning is just ignored.
    306   EXPECT_TRUE(Matches(factory.CreateQueryPrefixCondition("?sourceid"), url));
    307 
    308   EXPECT_TRUE(Matches(factory.CreateQuerySuffixCondition(std::string()), url));
    309   EXPECT_TRUE(Matches(factory.CreateQuerySuffixCondition("ion=1"), url));
    310   EXPECT_FALSE(Matches(factory.CreateQuerySuffixCondition("www"), url));
    311   // "Suffix" condition + pattern starting with '?' = "equals" condition.
    312   EXPECT_FALSE(Matches(factory.CreateQuerySuffixCondition(
    313       "?sourceid=chrome-instant&ie=UTF-8&ion="), url));
    314   EXPECT_TRUE(Matches(factory.CreateQuerySuffixCondition(
    315       "?sourceid=chrome-instant&ie=UTF-8&ion=1"), url));
    316 
    317   EXPECT_FALSE(Matches(factory.CreateQueryEqualsCondition(
    318       "?sourceid=chrome-instant&ie=UTF-8&ion="), url));
    319   EXPECT_FALSE(Matches(factory.CreateQueryEqualsCondition(
    320       "sourceid=chrome-instant&ie=UTF-8&ion="), url));
    321   EXPECT_TRUE(Matches(factory.CreateQueryEqualsCondition(
    322       "sourceid=chrome-instant&ie=UTF-8&ion=1"), url));
    323   // The '?' at the beginning is just ignored.
    324   EXPECT_TRUE(Matches(factory.CreateQueryEqualsCondition(
    325       "?sourceid=chrome-instant&ie=UTF-8&ion=1"), url));
    326   EXPECT_FALSE(
    327       Matches(factory.CreateQueryEqualsCondition("www.google.com"), url));
    328 
    329 
    330   // Test adjacent components
    331   EXPECT_TRUE(Matches(factory.CreateHostSuffixPathPrefixCondition(
    332       "google.com", "/webhp"), url));
    333   EXPECT_TRUE(Matches(
    334       factory.CreateHostSuffixPathPrefixCondition(std::string(), "/webhp"),
    335       url));
    336   EXPECT_TRUE(Matches(
    337       factory.CreateHostSuffixPathPrefixCondition("google.com", std::string()),
    338       url));
    339   EXPECT_FALSE(Matches(
    340       factory.CreateHostSuffixPathPrefixCondition("www", std::string()), url));
    341 
    342   EXPECT_TRUE(Matches(factory.CreateHostEqualsPathPrefixCondition(
    343       "www.google.com", "/webhp"), url));
    344   EXPECT_FALSE(Matches(
    345       factory.CreateHostEqualsPathPrefixCondition(std::string(), "/webhp"),
    346       url));
    347   EXPECT_TRUE(Matches(factory.CreateHostEqualsPathPrefixCondition(
    348                           "www.google.com", std::string()),
    349                       url));
    350   EXPECT_FALSE(Matches(
    351       factory.CreateHostEqualsPathPrefixCondition("google.com", std::string()),
    352       url));
    353 }
    354 
    355 TEST(URLMatcherConditionFactoryTest, TestFullSearches) {
    356   // The Port 443 is stripped because it is the default port for https.
    357   GURL gurl("https://www.google.com:443/webhp?sourceid=chrome-instant&ie=UTF-8"
    358       "&ion=1#hl=en&output=search&sclient=psy-ab&q=chrome%20is%20awesome");
    359   URLMatcherConditionFactory factory;
    360   std::string url = factory.CanonicalizeURLForFullSearches(gurl);
    361 
    362   EXPECT_TRUE(Matches(factory.CreateURLPrefixCondition(std::string()), url));
    363   EXPECT_TRUE(
    364       Matches(factory.CreateURLPrefixCondition("https://www.goog"), url));
    365   EXPECT_TRUE(Matches(factory.CreateURLPrefixCondition(
    366       "https://www.google.com"), url));
    367   EXPECT_TRUE(Matches(factory.CreateURLPrefixCondition(
    368       "https://www.google.com/webhp?"), url));
    369   EXPECT_FALSE(Matches(factory.CreateURLPrefixCondition(
    370       "http://www.google.com"), url));
    371   EXPECT_FALSE(Matches(factory.CreateURLPrefixCondition("webhp"), url));
    372 
    373   EXPECT_TRUE(Matches(factory.CreateURLSuffixCondition(std::string()), url));
    374   EXPECT_TRUE(Matches(factory.CreateURLSuffixCondition("ion=1"), url));
    375   EXPECT_FALSE(Matches(factory.CreateURLSuffixCondition("www"), url));
    376 
    377   EXPECT_TRUE(Matches(factory.CreateURLContainsCondition(std::string()), url));
    378   EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("www.goog"), url));
    379   EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("webhp"), url));
    380   EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("?"), url));
    381   EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("sourceid"), url));
    382   EXPECT_TRUE(Matches(factory.CreateURLContainsCondition("ion=1"), url));
    383   EXPECT_FALSE(Matches(factory.CreateURLContainsCondition(".www.goog"), url));
    384   EXPECT_FALSE(Matches(factory.CreateURLContainsCondition("foobar"), url));
    385   EXPECT_FALSE(Matches(factory.CreateURLContainsCondition("search"), url));
    386   EXPECT_FALSE(Matches(factory.CreateURLContainsCondition(":443"), url));
    387 
    388   EXPECT_TRUE(Matches(factory.CreateURLEqualsCondition(
    389       "https://www.google.com/webhp?sourceid=chrome-instant&ie=UTF-8&ion=1"),
    390       url));
    391   EXPECT_FALSE(
    392       Matches(factory.CreateURLEqualsCondition("https://www.google.com"), url));
    393 
    394   // Same as above but this time with a non-standard port.
    395   gurl = GURL("https://www.google.com:1234/webhp?sourceid=chrome-instant&"
    396       "ie=UTF-8&ion=1#hl=en&output=search&sclient=psy-ab&q=chrome%20is%20"
    397       "awesome");
    398   url = factory.CanonicalizeURLForFullSearches(gurl);
    399   EXPECT_TRUE(Matches(factory.CreateURLPrefixCondition(
    400       "https://www.google.com:1234/webhp?"), url));
    401   EXPECT_TRUE(Matches(factory.CreateURLContainsCondition(":1234"), url));
    402 }
    403 
    404 //
    405 // URLMatcherConditionSet
    406 //
    407 
    408 TEST(URLMatcherConditionSetTest, Constructor) {
    409   URLMatcherConditionFactory factory;
    410   URLMatcherCondition m1 = factory.CreateHostSuffixCondition("example.com");
    411   URLMatcherCondition m2 = factory.CreatePathContainsCondition("foo");
    412 
    413   std::set<URLMatcherCondition> conditions;
    414   conditions.insert(m1);
    415   conditions.insert(m2);
    416 
    417   scoped_refptr<URLMatcherConditionSet> condition_set(
    418       new URLMatcherConditionSet(1, conditions));
    419   EXPECT_EQ(1, condition_set->id());
    420   EXPECT_EQ(2u, condition_set->conditions().size());
    421 }
    422 
    423 TEST(URLMatcherConditionSetTest, Matching) {
    424   GURL url1("http://www.example.com/foo?bar=1");
    425   GURL url2("http://foo.example.com/index.html");
    426   GURL url3("http://www.example.com:80/foo?bar=1");
    427   GURL url4("http://www.example.com:8080/foo?bar=1");
    428 
    429   URLMatcherConditionFactory factory;
    430   URLMatcherCondition m1 = factory.CreateHostSuffixCondition("example.com");
    431   URLMatcherCondition m2 = factory.CreatePathContainsCondition("foo");
    432 
    433   std::set<URLMatcherCondition> conditions;
    434   conditions.insert(m1);
    435   conditions.insert(m2);
    436 
    437   scoped_refptr<URLMatcherConditionSet> condition_set(
    438       new URLMatcherConditionSet(1, conditions));
    439   EXPECT_EQ(1, condition_set->id());
    440   EXPECT_EQ(2u, condition_set->conditions().size());
    441 
    442   std::set<StringPattern::ID> matching_patterns;
    443   matching_patterns.insert(m1.string_pattern()->id());
    444   EXPECT_FALSE(condition_set->IsMatch(matching_patterns, url1));
    445 
    446   matching_patterns.insert(m2.string_pattern()->id());
    447   EXPECT_TRUE(condition_set->IsMatch(matching_patterns, url1));
    448   EXPECT_FALSE(condition_set->IsMatch(matching_patterns, url2));
    449 
    450   // Test scheme filters.
    451   scoped_refptr<URLMatcherConditionSet> condition_set2(
    452       new URLMatcherConditionSet(1,
    453                                  conditions,
    454                                  scoped_ptr<URLMatcherSchemeFilter>(
    455                                      new URLMatcherSchemeFilter("https")),
    456                                  scoped_ptr<URLMatcherPortFilter>()));
    457   EXPECT_FALSE(condition_set2->IsMatch(matching_patterns, url1));
    458   scoped_refptr<URLMatcherConditionSet> condition_set3(
    459       new URLMatcherConditionSet(1,
    460                                  conditions,
    461                                  scoped_ptr<URLMatcherSchemeFilter>(
    462                                      new URLMatcherSchemeFilter("http")),
    463                                  scoped_ptr<URLMatcherPortFilter>()));
    464   EXPECT_TRUE(condition_set3->IsMatch(matching_patterns, url1));
    465 
    466   // Test port filters.
    467   std::vector<URLMatcherPortFilter::Range> ranges;
    468   ranges.push_back(URLMatcherPortFilter::CreateRange(80));
    469   scoped_ptr<URLMatcherPortFilter> filter(new URLMatcherPortFilter(ranges));
    470   scoped_refptr<URLMatcherConditionSet> condition_set4(
    471       new URLMatcherConditionSet(
    472           1, conditions, scoped_ptr<URLMatcherSchemeFilter>(), filter.Pass()));
    473   EXPECT_TRUE(condition_set4->IsMatch(matching_patterns, url1));
    474   EXPECT_TRUE(condition_set4->IsMatch(matching_patterns, url3));
    475   EXPECT_FALSE(condition_set4->IsMatch(matching_patterns, url4));
    476 
    477   // Test regex patterns.
    478   matching_patterns.clear();
    479   URLMatcherCondition r1 = factory.CreateURLMatchesCondition("/fo?oo");
    480   std::set<URLMatcherCondition> regex_conditions;
    481   regex_conditions.insert(r1);
    482   scoped_refptr<URLMatcherConditionSet> condition_set5(
    483       new URLMatcherConditionSet(1, regex_conditions));
    484   EXPECT_FALSE(condition_set5->IsMatch(matching_patterns, url1));
    485   matching_patterns.insert(r1.string_pattern()->id());
    486   EXPECT_TRUE(condition_set5->IsMatch(matching_patterns, url1));
    487 
    488   regex_conditions.insert(m1);
    489   scoped_refptr<URLMatcherConditionSet> condition_set6(
    490       new URLMatcherConditionSet(1, regex_conditions));
    491   EXPECT_FALSE(condition_set6->IsMatch(matching_patterns, url1));
    492   matching_patterns.insert(m1.string_pattern()->id());
    493   EXPECT_TRUE(condition_set6->IsMatch(matching_patterns, url1));
    494 
    495   matching_patterns.clear();
    496   regex_conditions.clear();
    497   URLMatcherCondition r2 = factory.CreateOriginAndPathMatchesCondition("b[a]r");
    498   regex_conditions.insert(r2);
    499   scoped_refptr<URLMatcherConditionSet> condition_set7(
    500       new URLMatcherConditionSet(1, regex_conditions));
    501   EXPECT_FALSE(condition_set7->IsMatch(matching_patterns, url1));
    502   matching_patterns.insert(r2.string_pattern()->id());
    503   EXPECT_TRUE(condition_set7->IsMatch(matching_patterns, url1));
    504 }
    505 
    506 namespace {
    507 
    508 bool IsQueryMatch(
    509     const std::string& url_query,
    510     const std::string& key,
    511     URLQueryElementMatcherCondition::QueryElementType query_element_type,
    512     const std::string& value,
    513     URLQueryElementMatcherCondition::QueryValueMatchType query_value_match_type,
    514     URLQueryElementMatcherCondition::Type match_type) {
    515   URLMatcherConditionFactory factory;
    516 
    517   URLMatcherCondition m1 = factory.CreateHostSuffixCondition("example.com");
    518   URLMatcherCondition m2 = factory.CreatePathContainsCondition("foo");
    519   URLMatcherConditionSet::Conditions conditions;
    520   conditions.insert(m1);
    521   conditions.insert(m2);
    522 
    523   URLQueryElementMatcherCondition q1(key,
    524                                      value,
    525                                      query_value_match_type,
    526                                      query_element_type,
    527                                      match_type,
    528                                      &factory);
    529   URLMatcherConditionSet::QueryConditions query_conditions;
    530   query_conditions.insert(q1);
    531 
    532   scoped_ptr<URLMatcherSchemeFilter> scheme_filter;
    533   scoped_ptr<URLMatcherPortFilter> port_filter;
    534 
    535   scoped_refptr<URLMatcherConditionSet> condition_set(
    536       new URLMatcherConditionSet(1,
    537                                  conditions,
    538                                  query_conditions,
    539                                  scheme_filter.Pass(),
    540                                  port_filter.Pass()));
    541 
    542   GURL url("http://www.example.com/foo?" + url_query);
    543 
    544   URLMatcher matcher;
    545   URLMatcherConditionSet::Vector vector;
    546   vector.push_back(condition_set);
    547   matcher.AddConditionSets(vector);
    548 
    549   return matcher.MatchURL(url).size() == 1;
    550 }
    551 
    552 }  // namespace
    553 
    554 TEST(URLMatcherConditionSetTest, QueryMatching) {
    555   EXPECT_TRUE(
    556       IsQueryMatch("a=foo&b=foo&a=barr",
    557                    "a",
    558                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    559                    "bar",
    560                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
    561                    URLQueryElementMatcherCondition::MATCH_ANY));
    562   EXPECT_FALSE(
    563       IsQueryMatch("a=foo&b=foo&a=barr",
    564                    "a",
    565                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    566                    "bar",
    567                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    568                    URLQueryElementMatcherCondition::MATCH_ANY));
    569   EXPECT_TRUE(
    570       IsQueryMatch("a=foo&b=foo&a=barr",
    571                    "a",
    572                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    573                    "bar",
    574                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
    575                    URLQueryElementMatcherCondition::MATCH_ANY));
    576   EXPECT_FALSE(
    577       IsQueryMatch("a=foo&b=foo&a=barr",
    578                    "a",
    579                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    580                    "bar",
    581                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    582                    URLQueryElementMatcherCondition::MATCH_ANY));
    583   EXPECT_TRUE(
    584       IsQueryMatch("a&b=foo&a=barr",
    585                    "a",
    586                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    587                    "bar",
    588                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    589                    URLQueryElementMatcherCondition::MATCH_ANY));
    590   EXPECT_FALSE(
    591       IsQueryMatch("a=foo&b=foo&a=barr",
    592                    "a",
    593                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    594                    "bar",
    595                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    596                    URLQueryElementMatcherCondition::MATCH_ANY));
    597 
    598   EXPECT_FALSE(
    599       IsQueryMatch("a=foo&b=foo&a=bar",
    600                    "a",
    601                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    602                    "bar",
    603                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    604                    URLQueryElementMatcherCondition::MATCH_ALL));
    605   EXPECT_TRUE(
    606       IsQueryMatch("a=bar&b=foo&a=bar",
    607                    "a",
    608                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    609                    "bar",
    610                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    611                    URLQueryElementMatcherCondition::MATCH_ALL));
    612   EXPECT_TRUE(
    613       IsQueryMatch("a=bar&b=foo&a=bar",
    614                    "b",
    615                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    616                    "foo",
    617                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    618                    URLQueryElementMatcherCondition::MATCH_ALL));
    619   EXPECT_FALSE(
    620       IsQueryMatch("a=bar&b=foo&a=bar",
    621                    "b",
    622                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    623                    "goo",
    624                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    625                    URLQueryElementMatcherCondition::MATCH_ALL));
    626   EXPECT_FALSE(
    627       IsQueryMatch("a=bar&b=foo&a=bar",
    628                    "c",
    629                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    630                    "goo",
    631                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    632                    URLQueryElementMatcherCondition::MATCH_ALL));
    633   EXPECT_TRUE(
    634       IsQueryMatch("a=foo1&b=foo&a=foo2",
    635                    "a",
    636                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    637                    "foo",
    638                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
    639                    URLQueryElementMatcherCondition::MATCH_ALL));
    640   EXPECT_FALSE(
    641       IsQueryMatch("a=foo1&b=foo&a=fo02",
    642                    "a",
    643                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    644                    "foo",
    645                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
    646                    URLQueryElementMatcherCondition::MATCH_ALL));
    647   EXPECT_TRUE(
    648       IsQueryMatch("a&b=foo&a",
    649                    "a",
    650                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    651                    "foo",
    652                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
    653                    URLQueryElementMatcherCondition::MATCH_ALL));
    654   EXPECT_TRUE(
    655       IsQueryMatch("alt&b=foo",
    656                    "a",
    657                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    658                    "foo",
    659                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
    660                    URLQueryElementMatcherCondition::MATCH_ALL));
    661   EXPECT_TRUE(
    662       IsQueryMatch("b=foo&a",
    663                    "a",
    664                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    665                    "foo",
    666                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
    667                    URLQueryElementMatcherCondition::MATCH_ALL));
    668   EXPECT_FALSE(
    669       IsQueryMatch("b=foo",
    670                    "a",
    671                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    672                    "foo",
    673                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
    674                    URLQueryElementMatcherCondition::MATCH_ALL));
    675   EXPECT_TRUE(
    676       IsQueryMatch("b=foo&a",
    677                    "a",
    678                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    679                    "foo",
    680                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    681                    URLQueryElementMatcherCondition::MATCH_ALL));
    682 
    683   EXPECT_TRUE(
    684       IsQueryMatch("a=foo&b=foo&a=bar",
    685                    "a",
    686                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    687                    "foo",
    688                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    689                    URLQueryElementMatcherCondition::MATCH_FIRST));
    690   EXPECT_FALSE(
    691       IsQueryMatch("a=foo&b=foo&a=bar",
    692                    "a",
    693                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    694                    "bar",
    695                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    696                    URLQueryElementMatcherCondition::MATCH_FIRST));
    697   EXPECT_TRUE(
    698       IsQueryMatch("a=foo1&b=foo&a=bar",
    699                    "a",
    700                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    701                    "foo",
    702                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
    703                    URLQueryElementMatcherCondition::MATCH_FIRST));
    704   EXPECT_FALSE(
    705       IsQueryMatch("a=foo1&b=foo&a=bar",
    706                    "a",
    707                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    708                    "foo",
    709                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    710                    URLQueryElementMatcherCondition::MATCH_FIRST));
    711   EXPECT_TRUE(
    712       IsQueryMatch("a&b=foo&a=bar",
    713                    "a",
    714                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    715                    "foo",
    716                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    717                    URLQueryElementMatcherCondition::MATCH_FIRST));
    718   EXPECT_TRUE(
    719       IsQueryMatch("alt&b=foo&a=bar",
    720                    "a",
    721                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    722                    "foo",
    723                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
    724                    URLQueryElementMatcherCondition::MATCH_FIRST));
    725   EXPECT_FALSE(
    726       IsQueryMatch("alt&b=foo&a=bar",
    727                    "a",
    728                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    729                    "foo",
    730                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    731                    URLQueryElementMatcherCondition::MATCH_FIRST));
    732 
    733   EXPECT_FALSE(
    734       IsQueryMatch("a=foo&b=foo&a=bar",
    735                    "a",
    736                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    737                    "foo",
    738                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    739                    URLQueryElementMatcherCondition::MATCH_LAST));
    740   EXPECT_TRUE(
    741       IsQueryMatch("a=foo&b=foo&a=bar",
    742                    "a",
    743                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    744                    "bar",
    745                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    746                    URLQueryElementMatcherCondition::MATCH_LAST));
    747   EXPECT_FALSE(
    748       IsQueryMatch("a=foo1&b=foo&a=bar",
    749                    "a",
    750                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    751                    "foo",
    752                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
    753                    URLQueryElementMatcherCondition::MATCH_LAST));
    754   EXPECT_TRUE(
    755       IsQueryMatch("a=foo1&b=foo&a=bar1",
    756                    "a",
    757                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY_VALUE,
    758                    "bar",
    759                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
    760                    URLQueryElementMatcherCondition::MATCH_LAST));
    761   EXPECT_FALSE(
    762       IsQueryMatch("a&b=foo&a=bar",
    763                    "a",
    764                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    765                    "foo",
    766                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    767                    URLQueryElementMatcherCondition::MATCH_LAST));
    768   EXPECT_TRUE(
    769       IsQueryMatch("b=foo&alt",
    770                    "a",
    771                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    772                    "foo",
    773                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_PREFIX,
    774                    URLQueryElementMatcherCondition::MATCH_LAST));
    775   EXPECT_FALSE(
    776       IsQueryMatch("b=foo&alt",
    777                    "a",
    778                    URLQueryElementMatcherCondition::ELEMENT_TYPE_KEY,
    779                    "foo",
    780                    URLQueryElementMatcherCondition::QUERY_VALUE_MATCH_EXACT,
    781                    URLQueryElementMatcherCondition::MATCH_LAST));
    782 }
    783 
    784 //
    785 // URLMatcher
    786 //
    787 
    788 TEST(URLMatcherTest, FullTest) {
    789   GURL url1("http://www.example.com/foo?bar=1");
    790   GURL url2("http://foo.example.com/index.html");
    791 
    792   URLMatcher matcher;
    793   URLMatcherConditionFactory* factory = matcher.condition_factory();
    794 
    795   // First insert.
    796   URLMatcherConditionSet::Conditions conditions1;
    797   conditions1.insert(factory->CreateHostSuffixCondition("example.com"));
    798   conditions1.insert(factory->CreatePathContainsCondition("foo"));
    799 
    800   const int kConditionSetId1 = 1;
    801   URLMatcherConditionSet::Vector insert1;
    802   insert1.push_back(make_scoped_refptr(
    803       new URLMatcherConditionSet(kConditionSetId1, conditions1)));
    804   matcher.AddConditionSets(insert1);
    805   EXPECT_EQ(1u, matcher.MatchURL(url1).size());
    806   EXPECT_EQ(0u, matcher.MatchURL(url2).size());
    807 
    808   // Second insert.
    809   URLMatcherConditionSet::Conditions conditions2;
    810   conditions2.insert(factory->CreateHostSuffixCondition("example.com"));
    811 
    812   const int kConditionSetId2 = 2;
    813   URLMatcherConditionSet::Vector insert2;
    814   insert2.push_back(make_scoped_refptr(
    815       new URLMatcherConditionSet(kConditionSetId2, conditions2)));
    816   matcher.AddConditionSets(insert2);
    817   EXPECT_EQ(2u, matcher.MatchURL(url1).size());
    818   EXPECT_EQ(1u, matcher.MatchURL(url2).size());
    819 
    820   // This should be the cached singleton.
    821   int patternId1 = factory->CreateHostSuffixCondition(
    822       "example.com").string_pattern()->id();
    823 
    824   // Third insert.
    825   URLMatcherConditionSet::Conditions conditions3;
    826   conditions3.insert(factory->CreateHostSuffixCondition("example.com"));
    827   conditions3.insert(factory->CreateURLMatchesCondition("x.*[0-9]"));
    828 
    829   const int kConditionSetId3 = 3;
    830   URLMatcherConditionSet::Vector insert3;
    831   insert3.push_back(make_scoped_refptr(
    832       new URLMatcherConditionSet(kConditionSetId3, conditions3)));
    833   matcher.AddConditionSets(insert3);
    834   EXPECT_EQ(3u, matcher.MatchURL(url1).size());
    835   EXPECT_EQ(1u, matcher.MatchURL(url2).size());
    836 
    837   // Removal of third insert.
    838   std::vector<URLMatcherConditionSet::ID> remove3;
    839   remove3.push_back(kConditionSetId3);
    840   matcher.RemoveConditionSets(remove3);
    841   EXPECT_EQ(2u, matcher.MatchURL(url1).size());
    842   EXPECT_EQ(1u, matcher.MatchURL(url2).size());
    843 
    844   // Removal of second insert.
    845   std::vector<URLMatcherConditionSet::ID> remove2;
    846   remove2.push_back(kConditionSetId2);
    847   matcher.RemoveConditionSets(remove2);
    848   EXPECT_EQ(1u, matcher.MatchURL(url1).size());
    849   EXPECT_EQ(0u, matcher.MatchURL(url2).size());
    850 
    851   // Removal of first insert.
    852   std::vector<URLMatcherConditionSet::ID> remove1;
    853   remove1.push_back(kConditionSetId1);
    854   matcher.RemoveConditionSets(remove1);
    855   EXPECT_EQ(0u, matcher.MatchURL(url1).size());
    856   EXPECT_EQ(0u, matcher.MatchURL(url2).size());
    857 
    858   EXPECT_TRUE(matcher.IsEmpty());
    859 
    860   // The cached singleton in matcher.condition_factory_ should be destroyed to
    861   // free memory.
    862   int patternId2 = factory->CreateHostSuffixCondition(
    863       "example.com").string_pattern()->id();
    864   // If patternId1 and patternId2 are different that indicates that
    865   // matcher.condition_factory_ does not leak memory by holding onto
    866   // unused patterns.
    867   EXPECT_NE(patternId1, patternId2);
    868 }
    869 
    870 TEST(URLMatcherTest, TestComponentsImplyContains) {
    871   // Due to a different implementation of component (prefix, suffix and equals)
    872   // and *Contains conditions we need to check that when a pattern matches a
    873   // given part of a URL as equal, prefix or suffix, it also matches it in the
    874   // "contains" test.
    875   GURL url("https://www.google.com:1234/webhp?test=val&a=b");
    876 
    877   URLMatcher matcher;
    878   URLMatcherConditionFactory* factory = matcher.condition_factory();
    879 
    880   URLMatcherConditionSet::Conditions conditions;
    881 
    882   // First insert all the matching equals => contains pairs.
    883   conditions.insert(factory->CreateHostEqualsCondition("www.google.com"));
    884   conditions.insert(factory->CreateHostContainsCondition("www.google.com"));
    885 
    886   conditions.insert(factory->CreateHostPrefixCondition("www."));
    887   conditions.insert(factory->CreateHostContainsCondition("www."));
    888 
    889   conditions.insert(factory->CreateHostSuffixCondition("com"));
    890   conditions.insert(factory->CreateHostContainsCondition("com"));
    891 
    892   conditions.insert(factory->CreatePathEqualsCondition("/webhp"));
    893   conditions.insert(factory->CreatePathContainsCondition("/webhp"));
    894 
    895   conditions.insert(factory->CreatePathPrefixCondition("/we"));
    896   conditions.insert(factory->CreatePathContainsCondition("/we"));
    897 
    898   conditions.insert(factory->CreatePathSuffixCondition("hp"));
    899   conditions.insert(factory->CreatePathContainsCondition("hp"));
    900 
    901   conditions.insert(factory->CreateQueryEqualsCondition("test=val&a=b"));
    902   conditions.insert(factory->CreateQueryContainsCondition("test=val&a=b"));
    903 
    904   conditions.insert(factory->CreateQueryPrefixCondition("test=v"));
    905   conditions.insert(factory->CreateQueryContainsCondition("test=v"));
    906 
    907   conditions.insert(factory->CreateQuerySuffixCondition("l&a=b"));
    908   conditions.insert(factory->CreateQueryContainsCondition("l&a=b"));
    909 
    910   // The '?' for equality is just ignored.
    911   conditions.insert(factory->CreateQueryEqualsCondition("?test=val&a=b"));
    912   // Due to '?' the condition created here is a prefix-testing condition.
    913   conditions.insert(factory->CreateQueryContainsCondition("?test=val&a=b"));
    914 
    915   const int kConditionSetId = 1;
    916   URLMatcherConditionSet::Vector insert;
    917   insert.push_back(make_scoped_refptr(
    918       new URLMatcherConditionSet(kConditionSetId, conditions)));
    919   matcher.AddConditionSets(insert);
    920   EXPECT_EQ(1u, matcher.MatchURL(url).size());
    921 }
    922 
    923 // Check that matches in everything but the query are found.
    924 TEST(URLMatcherTest, TestOriginAndPathRegExPositive) {
    925   GURL url("https://www.google.com:1234/webhp?test=val&a=b");
    926 
    927   URLMatcher matcher;
    928   URLMatcherConditionFactory* factory = matcher.condition_factory();
    929 
    930   URLMatcherConditionSet::Conditions conditions;
    931 
    932   conditions.insert(factory->CreateOriginAndPathMatchesCondition("w..hp"));
    933   const int kConditionSetId = 1;
    934   URLMatcherConditionSet::Vector insert;
    935   insert.push_back(make_scoped_refptr(
    936       new URLMatcherConditionSet(kConditionSetId, conditions)));
    937   matcher.AddConditionSets(insert);
    938   EXPECT_EQ(1u, matcher.MatchURL(url).size());
    939 }
    940 
    941 // Check that matches in the query are ignored.
    942 TEST(URLMatcherTest, TestOriginAndPathRegExNegative) {
    943   GURL url("https://www.google.com:1234/webhp?test=val&a=b");
    944 
    945   URLMatcher matcher;
    946   URLMatcherConditionFactory* factory = matcher.condition_factory();
    947 
    948   URLMatcherConditionSet::Conditions conditions;
    949 
    950   conditions.insert(factory->CreateOriginAndPathMatchesCondition("val"));
    951   const int kConditionSetId = 1;
    952   URLMatcherConditionSet::Vector insert;
    953   insert.push_back(make_scoped_refptr(
    954       new URLMatcherConditionSet(kConditionSetId, conditions)));
    955   matcher.AddConditionSets(insert);
    956   EXPECT_EQ(0u, matcher.MatchURL(url).size());
    957 }
    958 
    959 }  // namespace url_matcher
    960