blob: 6bbaf90a90b5dca0a7bace47a6699cc8d5f12994 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/url_pattern_index/fuzzy_pattern_matching.h"
#include <vector>
#include "testing/gtest/include/gtest/gtest.h"
namespace url_pattern_index {
TEST(SubresourceFilterFuzzyPatternMatchingTest, StartsWithFuzzy) {
const struct {
const char* text;
const char* subpattern;
bool expected_starts_with;
} kTestCases[] = {
{"abc", "", true}, {"abc", "a", true}, {"abc", "ab", true},
{"abc", "abc", true}, {"abc", "abcd", false}, {"abc", "abc^^", false},
{"abc", "abcd^", false}, {"abc", "ab^", false}, {"abc", "bc", false},
{"abc", "bc^", false}, {"abc", "^abc", false},
};
// TODO(pkalinnikov): Make end-of-string match '^' again.
for (const auto& test_case : kTestCases) {
SCOPED_TRACE(testing::Message()
<< "Test: " << test_case.text
<< "; Subpattern: " << test_case.subpattern);
const bool starts_with =
StartsWithFuzzy(test_case.text, test_case.subpattern);
EXPECT_EQ(test_case.expected_starts_with, starts_with);
}
}
TEST(SubresourceFilterFuzzyPatternMatchingTest, EndsWithFuzzy) {
const struct {
const char* text;
const char* subpattern;
bool expected_ends_with;
} kTestCases[] = {
{"abc", "", true}, {"abc", "c", true}, {"abc", "bc", true},
{"abc", "abc", true}, {"abc", "0abc", false}, {"abc", "abc^^", false},
{"abc", "abcd^", false}, {"abc", "ab^", false}, {"abc", "ab", false},
{"abc", "^abc", false},
};
// TODO(pkalinnikov): Make end-of-string match '^' again.
for (const auto& test_case : kTestCases) {
SCOPED_TRACE(testing::Message()
<< "Test: " << test_case.text
<< "; Subpattern: " << test_case.subpattern);
const bool ends_with = EndsWithFuzzy(test_case.text, test_case.subpattern);
EXPECT_EQ(test_case.expected_ends_with, ends_with);
}
}
TEST(SubresourceFilterFuzzyPatternMatchingTest, FindFuzzy) {
const struct {
base::StringPiece text;
base::StringPiece subpattern;
std::vector<size_t> expected_occurrences;
} kTestCases[] = {
{"abcd", "", {0, 1, 2, 3, 4}},
{"abcd", "de", std::vector<size_t>()},
{"abcd", "ab", {0}},
{"abcd", "bc", {1}},
{"abcd", "cd", {2}},
{"a/bc/a/b", "", {0, 1, 2, 3, 4, 5, 6, 7, 8}},
{"a/bc/a/b", "de", std::vector<size_t>()},
{"a/bc/a/b", "a/", {0, 5}},
{"a/bc/a/c", "a/c", {5}},
{"a/bc/a/c", "a^c", {5}},
{"a/bc/a/c", "a?c", std::vector<size_t>()},
{"ab^cd", "ab/cd", std::vector<size_t>()},
{"ab^cd", "b/c", std::vector<size_t>()},
{"ab^cd", "ab^cd", {0}},
{"ab^cd", "b^c", {1}},
{"ab^b/b", "b/b", {3}},
{"a/a/a/a", "a/a", {0, 2, 4}},
{"a/a/a/a", "^a^a^a", {1}},
{"a/a/a/a", "^a^a?a", std::vector<size_t>()},
{"a/a/a/a", "?a?a?a", std::vector<size_t>()},
};
for (const auto& test_case : kTestCases) {
SCOPED_TRACE(testing::Message()
<< "Test: " << test_case.text
<< "; Subpattern: " << test_case.subpattern);
std::vector<size_t> occurrences;
for (size_t position = 0; position <= test_case.text.size(); ++position) {
position = FindFuzzy(test_case.text, test_case.subpattern, position);
if (position == base::StringPiece::npos)
break;
occurrences.push_back(position);
}
EXPECT_EQ(test_case.expected_occurrences, occurrences);
}
}
} // namespace url_pattern_index