| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <string> | 5 #include <string> |
| 6 #include <vector> | 6 #include <vector> |
| 7 | 7 |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
| 12 #include "chrome/browser/bookmarks/bookmark_index.h" | 12 #include "chrome/browser/bookmarks/bookmark_index.h" |
| 13 #include "chrome/browser/bookmarks/bookmark_model.h" | 13 #include "chrome/browser/bookmarks/bookmark_model.h" |
| 14 #include "chrome/browser/bookmarks/bookmark_utils.h" | 14 #include "chrome/browser/bookmarks/bookmark_utils.h" |
| 15 #include "chrome/browser/chrome_thread.h" | 15 #include "chrome/browser/chrome_thread.h" |
| 16 #include "chrome/browser/history/history_database.h" | 16 #include "chrome/browser/history/history_database.h" |
| 17 #include "chrome/browser/history/in_memory_database.h" | 17 #include "chrome/browser/history/in_memory_database.h" |
| 18 #include "chrome/browser/history/query_parser.h" | 18 #include "chrome/browser/history/query_parser.h" |
| 19 #include "chrome/test/testing_profile.h" | 19 #include "chrome/test/testing_profile.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 21 |
| 22 class BookmarkIndexTest : public testing::Test { | 22 class BookmarkIndexTest : public testing::Test { |
| 23 public: | 23 public: |
| 24 BookmarkIndexTest() : model_(new BookmarkModel(NULL)) {} | 24 BookmarkIndexTest() : model_(new BookmarkModel(NULL)) {} |
| 25 | 25 |
| 26 void AddBookmarksWithTitles(const wchar_t** titles, size_t count) { | 26 void AddBookmarksWithTitles(const char** titles, size_t count) { |
| 27 std::vector<std::wstring> title_vector; | 27 std::vector<std::string> title_vector; |
| 28 for (size_t i = 0; i < count; ++i) | 28 for (size_t i = 0; i < count; ++i) |
| 29 title_vector.push_back(titles[i]); | 29 title_vector.push_back(titles[i]); |
| 30 AddBookmarksWithTitles(title_vector); | 30 AddBookmarksWithTitles(title_vector); |
| 31 } | 31 } |
| 32 | 32 |
| 33 void AddBookmarksWithTitles(const std::vector<std::wstring>& titles) { | 33 void AddBookmarksWithTitles(const std::vector<std::string>& titles) { |
| 34 GURL url("about:blank"); | 34 GURL url("about:blank"); |
| 35 for (size_t i = 0; i < titles.size(); ++i) | 35 for (size_t i = 0; i < titles.size(); ++i) |
| 36 model_->AddURL(model_->other_node(), static_cast<int>(i), | 36 model_->AddURL(model_->other_node(), static_cast<int>(i), |
| 37 WideToUTF16Hack(titles[i]), url); | 37 ASCIIToUTF16(titles[i]), url); |
| 38 } | 38 } |
| 39 | 39 |
| 40 void ExpectMatches(const std::wstring& query, | 40 void ExpectMatches(const std::string& query, |
| 41 const wchar_t** expected_titles, | 41 const char** expected_titles, |
| 42 size_t expected_count) { | 42 size_t expected_count) { |
| 43 std::vector<std::wstring> title_vector; | 43 std::vector<std::string> title_vector; |
| 44 for (size_t i = 0; i < expected_count; ++i) | 44 for (size_t i = 0; i < expected_count; ++i) |
| 45 title_vector.push_back(expected_titles[i]); | 45 title_vector.push_back(expected_titles[i]); |
| 46 ExpectMatches(query, title_vector); | 46 ExpectMatches(query, title_vector); |
| 47 } | 47 } |
| 48 | 48 |
| 49 void ExpectMatches(const std::wstring& query, | 49 void ExpectMatches(const std::string& query, |
| 50 const std::vector<std::wstring> expected_titles) { | 50 const std::vector<std::string> expected_titles) { |
| 51 std::vector<bookmark_utils::TitleMatch> matches; | 51 std::vector<bookmark_utils::TitleMatch> matches; |
| 52 model_->GetBookmarksWithTitlesMatching(WideToUTF16Hack(query), 1000, | 52 model_->GetBookmarksWithTitlesMatching(ASCIIToUTF16(query), 1000, &matches); |
| 53 &matches); | |
| 54 ASSERT_EQ(expected_titles.size(), matches.size()); | 53 ASSERT_EQ(expected_titles.size(), matches.size()); |
| 55 for (size_t i = 0; i < expected_titles.size(); ++i) { | 54 for (size_t i = 0; i < expected_titles.size(); ++i) { |
| 56 bool found = false; | 55 bool found = false; |
| 57 for (size_t j = 0; j < matches.size(); ++j) { | 56 for (size_t j = 0; j < matches.size(); ++j) { |
| 58 if (std::wstring(expected_titles[i]) == matches[j].node->GetTitle()) { | 57 if (ASCIIToUTF16(expected_titles[i]) == |
| 58 matches[j].node->GetTitleAsString16()) { |
| 59 matches.erase(matches.begin() + j); | 59 matches.erase(matches.begin() + j); |
| 60 found = true; | 60 found = true; |
| 61 break; | 61 break; |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 ASSERT_TRUE(found); | 64 ASSERT_TRUE(found); |
| 65 } | 65 } |
| 66 } | 66 } |
| 67 | 67 |
| 68 void ExtractMatchPositions(const std::string& string, | 68 void ExtractMatchPositions(const std::string& string, |
| 69 Snippet::MatchPositions* matches) { | 69 Snippet::MatchPositions* matches) { |
| 70 std::vector<std::string> match_strings; | 70 std::vector<std::string> match_strings; |
| 71 SplitString(string, L':', &match_strings); | 71 SplitString(string, ':', &match_strings); |
| 72 for (size_t i = 0; i < match_strings.size(); ++i) { | 72 for (size_t i = 0; i < match_strings.size(); ++i) { |
| 73 std::vector<std::string> chunks; | 73 std::vector<std::string> chunks; |
| 74 SplitString(match_strings[i], ',', &chunks); | 74 SplitString(match_strings[i], ',', &chunks); |
| 75 ASSERT_EQ(2U, chunks.size()); | 75 ASSERT_EQ(2U, chunks.size()); |
| 76 matches->push_back(Snippet::MatchPosition()); | 76 matches->push_back(Snippet::MatchPosition()); |
| 77 int chunks0, chunks1; | 77 int chunks0, chunks1; |
| 78 base::StringToInt(chunks[0], &chunks0); | 78 base::StringToInt(chunks[0], &chunks0); |
| 79 base::StringToInt(chunks[1], &chunks1); | 79 base::StringToInt(chunks[1], &chunks1); |
| 80 matches->back().first = chunks0; | 80 matches->back().first = chunks0; |
| 81 matches->back().second = chunks1; | 81 matches->back().second = chunks1; |
| 82 } | 82 } |
| 83 } | 83 } |
| 84 | 84 |
| 85 void ExpectMatchPositions(const std::wstring& query, | 85 void ExpectMatchPositions(const std::string& query, |
| 86 const Snippet::MatchPositions& expected_positions) { | 86 const Snippet::MatchPositions& expected_positions) { |
| 87 std::vector<bookmark_utils::TitleMatch> matches; | 87 std::vector<bookmark_utils::TitleMatch> matches; |
| 88 model_->GetBookmarksWithTitlesMatching(WideToUTF16Hack(query), 1000, | 88 model_->GetBookmarksWithTitlesMatching(ASCIIToUTF16(query), 1000, &matches); |
| 89 &matches); | |
| 90 ASSERT_EQ(1U, matches.size()); | 89 ASSERT_EQ(1U, matches.size()); |
| 91 const bookmark_utils::TitleMatch& match = matches[0]; | 90 const bookmark_utils::TitleMatch& match = matches[0]; |
| 92 ASSERT_EQ(expected_positions.size(), match.match_positions.size()); | 91 ASSERT_EQ(expected_positions.size(), match.match_positions.size()); |
| 93 for (size_t i = 0; i < expected_positions.size(); ++i) { | 92 for (size_t i = 0; i < expected_positions.size(); ++i) { |
| 94 EXPECT_EQ(expected_positions[i].first, match.match_positions[i].first); | 93 EXPECT_EQ(expected_positions[i].first, match.match_positions[i].first); |
| 95 EXPECT_EQ(expected_positions[i].second, match.match_positions[i].second); | 94 EXPECT_EQ(expected_positions[i].second, match.match_positions[i].second); |
| 96 } | 95 } |
| 97 } | 96 } |
| 98 | 97 |
| 99 protected: | 98 protected: |
| 100 scoped_ptr<BookmarkModel> model_; | 99 scoped_ptr<BookmarkModel> model_; |
| 101 | 100 |
| 102 private: | 101 private: |
| 103 DISALLOW_COPY_AND_ASSIGN(BookmarkIndexTest); | 102 DISALLOW_COPY_AND_ASSIGN(BookmarkIndexTest); |
| 104 }; | 103 }; |
| 105 | 104 |
| 106 // Various permutations with differing input, queries and output that exercises | 105 // Various permutations with differing input, queries and output that exercises |
| 107 // all query paths. | 106 // all query paths. |
| 108 TEST_F(BookmarkIndexTest, Tests) { | 107 TEST_F(BookmarkIndexTest, Tests) { |
| 109 struct TestData { | 108 struct TestData { |
| 110 const std::wstring input; | 109 const std::string input; |
| 111 const std::wstring query; | 110 const std::string query; |
| 112 const std::wstring expected; | 111 const std::string expected; |
| 113 } data[] = { | 112 } data[] = { |
| 114 // Trivial test case of only one term, exact match. | 113 // Trivial test case of only one term, exact match. |
| 115 { L"a;b", L"A", L"a" }, | 114 { "a;b", "A", "a" }, |
| 116 | 115 |
| 117 // Prefix match, one term. | 116 // Prefix match, one term. |
| 118 { L"abcd;abc;b", L"abc", L"abcd;abc" }, | 117 { "abcd;abc;b", "abc", "abcd;abc" }, |
| 119 | 118 |
| 120 // Prefix match, multiple terms. | 119 // Prefix match, multiple terms. |
| 121 { L"abcd cdef;abcd;abcd cdefg", L"abc cde", L"abcd cdef;abcd cdefg"}, | 120 { "abcd cdef;abcd;abcd cdefg", "abc cde", "abcd cdef;abcd cdefg"}, |
| 122 | 121 |
| 123 // Exact and prefix match. | 122 // Exact and prefix match. |
| 124 { L"ab cdef;abcd;abcd cdefg", L"ab cdef", L"ab cdef"}, | 123 { "ab cdef;abcd;abcd cdefg", "ab cdef", "ab cdef"}, |
| 125 | 124 |
| 126 // Exact and prefix match. | 125 // Exact and prefix match. |
| 127 { L"ab cdef ghij;ab;cde;cdef;ghi;cdef ab;ghij ab", | 126 { "ab cdef ghij;ab;cde;cdef;ghi;cdef ab;ghij ab", |
| 128 L"ab cde ghi", | 127 "ab cde ghi", |
| 129 L"ab cdef ghij"}, | 128 "ab cdef ghij"}, |
| 130 | 129 |
| 131 // Title with term multiple times. | 130 // Title with term multiple times. |
| 132 { L"ab ab", L"ab", L"ab ab"}, | 131 { "ab ab", "ab", "ab ab"}, |
| 133 | 132 |
| 134 // Make sure quotes don't do a prefix match. | 133 // Make sure quotes don't do a prefix match. |
| 135 { L"think", L"\"thi\"", L""}, | 134 { "think", "\"thi\"", ""}, |
| 136 }; | 135 }; |
| 137 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { | 136 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { |
| 138 std::vector<std::wstring> titles; | 137 std::vector<std::string> titles; |
| 139 SplitString(data[i].input, L';', &titles); | 138 SplitString(data[i].input, ';', &titles); |
| 140 AddBookmarksWithTitles(titles); | 139 AddBookmarksWithTitles(titles); |
| 141 | 140 |
| 142 std::vector<std::wstring> expected; | 141 std::vector<std::string> expected; |
| 143 if (!data[i].expected.empty()) | 142 if (!data[i].expected.empty()) |
| 144 SplitString(data[i].expected, L';', &expected); | 143 SplitString(data[i].expected, ';', &expected); |
| 145 | 144 |
| 146 ExpectMatches(data[i].query, expected); | 145 ExpectMatches(data[i].query, expected); |
| 147 | 146 |
| 148 model_.reset(new BookmarkModel(NULL)); | 147 model_.reset(new BookmarkModel(NULL)); |
| 149 } | 148 } |
| 150 } | 149 } |
| 151 | 150 |
| 152 // Makes sure match positions are updated appropriately. | 151 // Makes sure match positions are updated appropriately. |
| 153 TEST_F(BookmarkIndexTest, MatchPositions) { | 152 TEST_F(BookmarkIndexTest, MatchPositions) { |
| 154 struct TestData { | 153 struct TestData { |
| 155 const std::wstring title; | 154 const std::string title; |
| 156 const std::wstring query; | 155 const std::string query; |
| 157 const std::string expected; | 156 const std::string expected; |
| 158 } data[] = { | 157 } data[] = { |
| 159 // Trivial test case of only one term, exact match. | 158 // Trivial test case of only one term, exact match. |
| 160 { L"a", L"A", "0,1" }, | 159 { "a", "A", "0,1" }, |
| 161 { L"foo bar", L"bar", "4,7" }, | 160 { "foo bar", "bar", "4,7" }, |
| 162 { L"fooey bark", L"bar foo", "0,3:6,9"}, | 161 { "fooey bark", "bar foo", "0,3:6,9"}, |
| 163 }; | 162 }; |
| 164 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { | 163 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { |
| 165 std::vector<std::wstring> titles; | 164 std::vector<std::string> titles; |
| 166 titles.push_back(data[i].title); | 165 titles.push_back(data[i].title); |
| 167 AddBookmarksWithTitles(titles); | 166 AddBookmarksWithTitles(titles); |
| 168 | 167 |
| 169 Snippet::MatchPositions expected_matches; | 168 Snippet::MatchPositions expected_matches; |
| 170 ExtractMatchPositions(data[i].expected, &expected_matches); | 169 ExtractMatchPositions(data[i].expected, &expected_matches); |
| 171 ExpectMatchPositions(data[i].query, expected_matches); | 170 ExpectMatchPositions(data[i].query, expected_matches); |
| 172 | 171 |
| 173 model_.reset(new BookmarkModel(NULL)); | 172 model_.reset(new BookmarkModel(NULL)); |
| 174 } | 173 } |
| 175 } | 174 } |
| 176 | 175 |
| 177 // Makes sure index is updated when a node is removed. | 176 // Makes sure index is updated when a node is removed. |
| 178 TEST_F(BookmarkIndexTest, Remove) { | 177 TEST_F(BookmarkIndexTest, Remove) { |
| 179 const wchar_t* input[] = { L"a", L"b" }; | 178 const char* input[] = { "a", "b" }; |
| 180 AddBookmarksWithTitles(input, ARRAYSIZE_UNSAFE(input)); | 179 AddBookmarksWithTitles(input, ARRAYSIZE_UNSAFE(input)); |
| 181 | 180 |
| 182 // Remove the node and make sure we don't get back any results. | 181 // Remove the node and make sure we don't get back any results. |
| 183 model_->Remove(model_->other_node(), 0); | 182 model_->Remove(model_->other_node(), 0); |
| 184 ExpectMatches(L"A", NULL, 0U); | 183 ExpectMatches("A", NULL, 0U); |
| 185 } | 184 } |
| 186 | 185 |
| 187 // Makes sure index is updated when a node's title is changed. | 186 // Makes sure index is updated when a node's title is changed. |
| 188 TEST_F(BookmarkIndexTest, ChangeTitle) { | 187 TEST_F(BookmarkIndexTest, ChangeTitle) { |
| 189 const wchar_t* input[] = { L"a", L"b" }; | 188 const char* input[] = { "a", "b" }; |
| 190 AddBookmarksWithTitles(input, ARRAYSIZE_UNSAFE(input)); | 189 AddBookmarksWithTitles(input, ARRAYSIZE_UNSAFE(input)); |
| 191 | 190 |
| 192 // Remove the node and make sure we don't get back any results. | 191 // Remove the node and make sure we don't get back any results. |
| 193 const wchar_t* expected[] = { L"blah" }; | 192 const char* expected[] = { "blah" }; |
| 194 model_->SetTitle(model_->other_node()->GetChild(0), ASCIIToUTF16("blah")); | 193 model_->SetTitle(model_->other_node()->GetChild(0), ASCIIToUTF16("blah")); |
| 195 ExpectMatches(L"BlAh", expected, ARRAYSIZE_UNSAFE(expected)); | 194 ExpectMatches("BlAh", expected, ARRAYSIZE_UNSAFE(expected)); |
| 196 } | 195 } |
| 197 | 196 |
| 198 // Makes sure no more than max queries is returned. | 197 // Makes sure no more than max queries is returned. |
| 199 TEST_F(BookmarkIndexTest, HonorMax) { | 198 TEST_F(BookmarkIndexTest, HonorMax) { |
| 200 const wchar_t* input[] = { L"abcd", L"abcde" }; | 199 const char* input[] = { "abcd", "abcde" }; |
| 201 AddBookmarksWithTitles(input, ARRAYSIZE_UNSAFE(input)); | 200 AddBookmarksWithTitles(input, ARRAYSIZE_UNSAFE(input)); |
| 202 | 201 |
| 203 std::vector<bookmark_utils::TitleMatch> matches; | 202 std::vector<bookmark_utils::TitleMatch> matches; |
| 204 model_->GetBookmarksWithTitlesMatching(ASCIIToUTF16("ABc"), 1, &matches); | 203 model_->GetBookmarksWithTitlesMatching(ASCIIToUTF16("ABc"), 1, &matches); |
| 205 EXPECT_EQ(1U, matches.size()); | 204 EXPECT_EQ(1U, matches.size()); |
| 206 } | 205 } |
| 207 | 206 |
| 208 // Makes sure if the lower case string of a bookmark title is more characters | 207 // Makes sure if the lower case string of a bookmark title is more characters |
| 209 // than the upper case string no match positions are returned. | 208 // than the upper case string no match positions are returned. |
| 210 TEST_F(BookmarkIndexTest, EmptyMatchOnMultiwideLowercaseString) { | 209 TEST_F(BookmarkIndexTest, EmptyMatchOnMultiwideLowercaseString) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 | 294 |
| 296 matches.clear(); | 295 matches.clear(); |
| 297 // Select top two matches. | 296 // Select top two matches. |
| 298 model->GetBookmarksWithTitlesMatching(ASCIIToUTF16("google"), 2, &matches); | 297 model->GetBookmarksWithTitlesMatching(ASCIIToUTF16("google"), 2, &matches); |
| 299 | 298 |
| 300 EXPECT_EQ(2, static_cast<int>(matches.size())); | 299 EXPECT_EQ(2, static_cast<int>(matches.size())); |
| 301 EXPECT_EQ(data[0].url, matches[0].node->GetURL()); | 300 EXPECT_EQ(data[0].url, matches[0].node->GetURL()); |
| 302 EXPECT_EQ(data[3].url, matches[1].node->GetURL()); | 301 EXPECT_EQ(data[3].url, matches[1].node->GetURL()); |
| 303 } | 302 } |
| 304 | 303 |
| OLD | NEW |