1// Copyright (c) 2012 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 "extensions/common/matcher/substring_set_matcher.h" 6 7#include <set> 8#include <string> 9#include <vector> 10 11#include "testing/gtest/include/gtest/gtest.h" 12 13using extensions::StringPattern; 14using extensions::SubstringSetMatcher; 15 16namespace { 17void TestOnePattern(const std::string& test_string, 18 const std::string& pattern, 19 bool is_match) { 20 std::string test = 21 "TestOnePattern(" + test_string + ", " + pattern + ", " + 22 (is_match ? "1" : "0") + ")"; 23 std::vector<const StringPattern*> patterns; 24 StringPattern substring_pattern(pattern, 1); 25 patterns.push_back(&substring_pattern); 26 SubstringSetMatcher matcher; 27 matcher.RegisterPatterns(patterns); 28 std::set<int> matches; 29 matcher.Match(test_string, &matches); 30 31 size_t expected_matches = (is_match ? 1 : 0); 32 EXPECT_EQ(expected_matches, matches.size()) << test; 33 EXPECT_EQ(is_match, matches.find(1) != matches.end()) << test; 34} 35 36void TestTwoPatterns(const std::string& test_string, 37 const std::string& pattern_1, 38 const std::string& pattern_2, 39 bool is_match_1, 40 bool is_match_2) { 41 std::string test = 42 "TestTwoPatterns(" + test_string + ", " + pattern_1 + ", " + pattern_2 + 43 ", " + (is_match_1 ? "1" : "0") + ", " + (is_match_2 ? "1" : "0") + ")"; 44 StringPattern substring_pattern_1(pattern_1, 1); 45 StringPattern substring_pattern_2(pattern_2, 2); 46 // In order to make sure that the order in which patterns are registered 47 // does not make any difference we try both permutations. 48 for (int permutation = 0; permutation < 2; ++permutation) { 49 std::vector<const StringPattern*> patterns; 50 if (permutation == 0) { 51 patterns.push_back(&substring_pattern_1); 52 patterns.push_back(&substring_pattern_2); 53 } else { 54 patterns.push_back(&substring_pattern_2); 55 patterns.push_back(&substring_pattern_1); 56 } 57 SubstringSetMatcher matcher; 58 matcher.RegisterPatterns(patterns); 59 std::set<int> matches; 60 matcher.Match(test_string, &matches); 61 62 size_t expected_matches = (is_match_1 ? 1 : 0) + (is_match_2 ? 1 : 0); 63 EXPECT_EQ(expected_matches, matches.size()) << test; 64 EXPECT_EQ(is_match_1, matches.find(1) != matches.end()) << test; 65 EXPECT_EQ(is_match_2, matches.find(2) != matches.end()) << test; 66 } 67} 68} 69 70TEST(SubstringSetMatcherTest, TestMatcher) { 71 // Test overlapping patterns 72 // String abcde 73 // Pattern 1 bc 74 // Pattern 2 cd 75 TestTwoPatterns("abcde", "bc", "cd", true, true); 76 77 // Test subpatterns - part 1 78 // String abcde 79 // Pattern 1 bc 80 // Pattern 2 b 81 TestTwoPatterns("abcde", "bc", "b", true, true); 82 83 // Test subpatterns - part 2 84 // String abcde 85 // Pattern 1 bc 86 // Pattern 2 c 87 TestTwoPatterns("abcde", "bc", "c", true, true); 88 89 // Test identical matches 90 // String abcde 91 // Pattern 1 abcde 92 TestOnePattern("abcde", "abcde", true); 93 94 // Test multiple matches 95 // String aaaaa 96 // Pattern 1 a 97 TestOnePattern("abcde", "a", true); 98 99 // Test matches at beginning and end 100 // String abcde 101 // Pattern 1 ab 102 // Pattern 2 de 103 TestTwoPatterns("abcde", "ab", "de", true, true); 104 105 // Test duplicate patterns with different IDs 106 // String abcde 107 // Pattern 1 bc 108 // Pattern 2 bc 109 TestTwoPatterns("abcde", "bc", "bc", true, true); 110 111 // Test non-match 112 // String abcde 113 // Pattern 1 fg 114 TestOnePattern("abcde", "fg", false); 115 116 // Test empty pattern and too long pattern 117 // String abcde 118 // Pattern 1 119 // Pattern 2 abcdef 120 TestTwoPatterns("abcde", std::string(), "abcdef", true, false); 121} 122 123TEST(SubstringSetMatcherTest, RegisterAndRemove) { 124 SubstringSetMatcher matcher; 125 126 StringPattern pattern_1("a", 1); 127 StringPattern pattern_2("b", 2); 128 StringPattern pattern_3("c", 3); 129 130 std::vector<const StringPattern*> patterns; 131 patterns.push_back(&pattern_1); 132 matcher.RegisterPatterns(patterns); 133 134 patterns.clear(); 135 patterns.push_back(&pattern_2); 136 patterns.push_back(&pattern_3); 137 matcher.RegisterPatterns(patterns); 138 139 std::set<int> matches; 140 matcher.Match("abd", &matches); 141 EXPECT_EQ(2u, matches.size()); 142 EXPECT_TRUE(matches.end() != matches.find(1)); 143 EXPECT_TRUE(matches.end() != matches.find(2)); 144 145 patterns.clear(); 146 patterns.push_back(&pattern_2); 147 matcher.UnregisterPatterns(patterns); 148 149 matches.clear(); 150 matcher.Match("abd", &matches); 151 EXPECT_EQ(1u, matches.size()); 152 EXPECT_TRUE(matches.end() != matches.find(1)); 153 EXPECT_TRUE(matches.end() == matches.find(2)); 154 155 patterns.clear(); 156 patterns.push_back(&pattern_1); 157 patterns.push_back(&pattern_3); 158 matcher.UnregisterPatterns(patterns); 159 EXPECT_TRUE(matcher.IsEmpty()); 160} 161 162TEST(SubstringSetMatcherTest, TestEmptyMatcher) { 163 SubstringSetMatcher matcher; 164 std::set<int> matches; 165 matcher.Match("abd", &matches); 166 EXPECT_TRUE(matches.empty()); 167} 168