1 // Copyright (c) 2006-2008 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 "base/utf_string_conversions.h" 6 #include "chrome/browser/history/history_types.h" 7 #include "testing/gtest/include/gtest/gtest.h" 8 9 namespace history { 10 11 namespace { 12 13 // Validates the consistency of the given history result. We just make sure 14 // that the URL rows match the indices structure. The unit tests themselves 15 // test the index structure to verify things are in the right order, so we 16 // don't need to. 17 void CheckHistoryResultConsistency(const QueryResults& result) { 18 for (size_t i = 0; i < result.size(); i++) { 19 size_t match_count; 20 const size_t* matches = result.MatchesForURL(result[i].url(), &match_count); 21 22 bool found = false; 23 for (size_t match = 0; match < match_count; match++) { 24 if (matches[match] == i) { 25 found = true; 26 break; 27 } 28 } 29 30 EXPECT_TRUE(found) << "The URL had no index referring to it."; 31 } 32 } 33 34 static const char kURL1[] = "http://www.google.com/"; 35 static const char kURL2[] = "http://news.google.com/"; 36 static const char kURL3[] = "http://images.google.com/"; 37 38 // Adds kURL1 twice and kURL2 once. 39 void AddSimpleData(QueryResults* results) { 40 GURL url1(kURL1); 41 GURL url2(kURL2); 42 URLResult result1(url1, base::Time::Now()); 43 URLResult result2(url1, base::Time::Now()); 44 URLResult result3(url2, base::Time::Now()); 45 46 // The URLResults are invalid after being inserted. 47 results->AppendURLBySwapping(&result1); 48 results->AppendURLBySwapping(&result2); 49 results->AppendURLBySwapping(&result3); 50 CheckHistoryResultConsistency(*results); 51 } 52 53 // Adds kURL2 once and kURL3 once. 54 void AddAlternateData(QueryResults* results) { 55 GURL url2(kURL2); 56 GURL url3(kURL3); 57 URLResult result1(url2, base::Time::Now()); 58 URLResult result2(url3, base::Time::Now()); 59 60 // The URLResults are invalid after being inserted. 61 results->AppendURLBySwapping(&result1); 62 results->AppendURLBySwapping(&result2); 63 CheckHistoryResultConsistency(*results); 64 } 65 66 } // namespace 67 68 // Tests insertion and deletion by range. 69 TEST(HistoryQueryResult, DeleteRange) { 70 GURL url1(kURL1); 71 GURL url2(kURL2); 72 QueryResults results; 73 AddSimpleData(&results); 74 75 // Make sure the first URL is in there twice. The indices can be in either 76 // order. 77 size_t match_count; 78 const size_t* matches = results.MatchesForURL(url1, &match_count); 79 ASSERT_EQ(2U, match_count); 80 EXPECT_TRUE((matches[0] == 0 && matches[1] == 1) || 81 (matches[0] == 1 && matches[1] == 0)); 82 83 // Check the second one. 84 matches = results.MatchesForURL(url2, &match_count); 85 ASSERT_EQ(1U, match_count); 86 EXPECT_TRUE(matches[0] == 2); 87 88 // Delete the first instance of the first URL. 89 results.DeleteRange(0, 0); 90 CheckHistoryResultConsistency(results); 91 92 // Check the two URLs. 93 matches = results.MatchesForURL(url1, &match_count); 94 ASSERT_EQ(1U, match_count); 95 EXPECT_TRUE(matches[0] == 0); 96 matches = results.MatchesForURL(url2, &match_count); 97 ASSERT_EQ(1U, match_count); 98 EXPECT_TRUE(matches[0] == 1); 99 100 // Now delete everything and make sure it's deleted. 101 results.DeleteRange(0, 1); 102 EXPECT_EQ(0U, results.size()); 103 EXPECT_FALSE(results.MatchesForURL(url1, NULL)); 104 EXPECT_FALSE(results.MatchesForURL(url2, NULL)); 105 } 106 107 // Tests insertion and deletion by URL. 108 TEST(HistoryQueryResult, ResultDeleteURL) { 109 GURL url1(kURL1); 110 GURL url2(kURL2); 111 QueryResults results; 112 AddSimpleData(&results); 113 114 // Delete the first URL. 115 results.DeleteURL(url1); 116 CheckHistoryResultConsistency(results); 117 EXPECT_EQ(1U, results.size()); 118 119 // The first one should be gone, and the second one should be at [0]. 120 size_t match_count; 121 EXPECT_FALSE(results.MatchesForURL(url1, NULL)); 122 const size_t* matches = results.MatchesForURL(url2, &match_count); 123 ASSERT_EQ(1U, match_count); 124 EXPECT_TRUE(matches[0] == 0); 125 126 // Delete the second URL, there should be nothing left. 127 results.DeleteURL(url2); 128 EXPECT_EQ(0U, results.size()); 129 EXPECT_FALSE(results.MatchesForURL(url2, NULL)); 130 } 131 132 TEST(HistoryQueryResult, AppendResults) { 133 GURL url1(kURL1); 134 GURL url2(kURL2); 135 GURL url3(kURL3); 136 137 // This is the base. 138 QueryResults results; 139 AddSimpleData(&results); 140 141 // Now create the appendee. 142 QueryResults appendee; 143 AddAlternateData(&appendee); 144 145 results.AppendResultsBySwapping(&appendee, true); 146 CheckHistoryResultConsistency(results); 147 148 // There should be 3 results, the second one of the appendee should be 149 // deleted because it was already in the first one and we said remove dupes. 150 ASSERT_EQ(4U, results.size()); 151 152 // The first URL should be unchanged in the first two spots. 153 size_t match_count; 154 const size_t* matches = results.MatchesForURL(url1, &match_count); 155 ASSERT_EQ(2U, match_count); 156 EXPECT_TRUE((matches[0] == 0 && matches[1] == 1) || 157 (matches[0] == 1 && matches[1] == 0)); 158 159 // The second URL should be there once after that 160 matches = results.MatchesForURL(url2, &match_count); 161 ASSERT_EQ(1U, match_count); 162 EXPECT_TRUE(matches[0] == 2); 163 164 // The third one should be after that. 165 matches = results.MatchesForURL(url3, &match_count); 166 ASSERT_EQ(1U, match_count); 167 EXPECT_TRUE(matches[0] == 3); 168 } 169 170 TEST(HistoryQueryResult, RowSignificance) { 171 const base::Time& threshold(AutocompleteAgeThreshold()); 172 const GURL url("http://www.google.com/"); 173 URLRow url_row(url); 174 url_row.set_title(UTF8ToUTF16("Google")); 175 EXPECT_FALSE(RowQualifiesAsSignificant(url_row, threshold)); 176 EXPECT_FALSE(RowQualifiesAsSignificant(url_row, base::Time())); 177 url_row.set_visit_count(kLowQualityMatchVisitLimit + 1); 178 EXPECT_TRUE(RowQualifiesAsSignificant(url_row, threshold)); 179 EXPECT_TRUE(RowQualifiesAsSignificant(url_row, base::Time())); 180 url_row.set_visit_count(1); 181 EXPECT_FALSE(RowQualifiesAsSignificant(url_row, threshold)); 182 EXPECT_FALSE(RowQualifiesAsSignificant(url_row, base::Time())); 183 url_row.set_typed_count(kLowQualityMatchTypedLimit + 1); 184 EXPECT_TRUE(RowQualifiesAsSignificant(url_row, threshold)); 185 EXPECT_TRUE(RowQualifiesAsSignificant(url_row, base::Time())); 186 url_row.set_typed_count(0); 187 EXPECT_FALSE(RowQualifiesAsSignificant(url_row, threshold)); 188 EXPECT_FALSE(RowQualifiesAsSignificant(url_row, base::Time())); 189 url_row.set_last_visit(base::Time::Now() - base::TimeDelta::FromDays(1)); 190 EXPECT_TRUE(RowQualifiesAsSignificant(url_row, threshold)); 191 EXPECT_TRUE(RowQualifiesAsSignificant(url_row, base::Time())); 192 url_row.set_last_visit(base::Time::Now() - 193 base::TimeDelta::FromDays(kLowQualityMatchAgeLimitInDays + 1)); 194 EXPECT_FALSE(RowQualifiesAsSignificant(url_row, threshold)); 195 EXPECT_FALSE(RowQualifiesAsSignificant(url_row, base::Time())); 196 } 197 198 } // namespace 199