// 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 #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 expected_occurrences; } kTestCases[] = { {"abcd", "", {0, 1, 2, 3, 4}}, {"abcd", "de", std::vector()}, {"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()}, {"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()}, {"ab^cd", "ab/cd", std::vector()}, {"ab^cd", "b/c", std::vector()}, {"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()}, {"a/a/a/a", "?a?a?a", std::vector()}, }; for (const auto& test_case : kTestCases) { SCOPED_TRACE(testing::Message() << "Test: " << test_case.text << "; Subpattern: " << test_case.subpattern); std::vector 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