Home | History | Annotate | Download | only in history
      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