1// Copyright (c) 2011 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/strings/utf_string_conversions.h"
6#include "components/history/core/browser/history_types.h"
7#include "testing/gtest/include/gtest/gtest.h"
8
9namespace history {
10
11namespace {
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.
17void 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
34const char kURL1[] = "http://www.google.com/";
35const char kURL2[] = "http://news.google.com/";
36
37// Adds kURL1 twice and kURL2 once.
38void AddSimpleData(QueryResults* results) {
39  GURL url1(kURL1);
40  GURL url2(kURL2);
41  URLResult result1(url1, base::Time::Now());
42  URLResult result2(url1, base::Time::Now());
43  URLResult result3(url2, base::Time::Now());
44
45  // The URLResults are invalid after being inserted.
46  results->AppendURLBySwapping(&result1);
47  results->AppendURLBySwapping(&result2);
48  results->AppendURLBySwapping(&result3);
49  CheckHistoryResultConsistency(*results);
50}
51
52}  // namespace
53
54// Tests insertion and deletion by range.
55TEST(HistoryQueryResult, DeleteRange) {
56  GURL url1(kURL1);
57  GURL url2(kURL2);
58  QueryResults results;
59  AddSimpleData(&results);
60
61  // Make sure the first URL is in there twice. The indices can be in either
62  // order.
63  size_t match_count;
64  const size_t* matches = results.MatchesForURL(url1, &match_count);
65  ASSERT_EQ(2U, match_count);
66  EXPECT_TRUE((matches[0] == 0 && matches[1] == 1) ||
67              (matches[0] == 1 && matches[1] == 0));
68
69  // Check the second one.
70  matches = results.MatchesForURL(url2, &match_count);
71  ASSERT_EQ(1U, match_count);
72  EXPECT_TRUE(matches[0] == 2);
73
74  // Delete the first instance of the first URL.
75  results.DeleteRange(0, 0);
76  CheckHistoryResultConsistency(results);
77
78  // Check the two URLs.
79  matches = results.MatchesForURL(url1, &match_count);
80  ASSERT_EQ(1U, match_count);
81  EXPECT_TRUE(matches[0] == 0);
82  matches = results.MatchesForURL(url2, &match_count);
83  ASSERT_EQ(1U, match_count);
84  EXPECT_TRUE(matches[0] == 1);
85
86  // Now delete everything and make sure it's deleted.
87  results.DeleteRange(0, 1);
88  EXPECT_EQ(0U, results.size());
89  EXPECT_FALSE(results.MatchesForURL(url1, NULL));
90  EXPECT_FALSE(results.MatchesForURL(url2, NULL));
91}
92
93// Tests insertion and deletion by URL.
94TEST(HistoryQueryResult, ResultDeleteURL) {
95  GURL url1(kURL1);
96  GURL url2(kURL2);
97  QueryResults results;
98  AddSimpleData(&results);
99
100  // Delete the first URL.
101  results.DeleteURL(url1);
102  CheckHistoryResultConsistency(results);
103  EXPECT_EQ(1U, results.size());
104
105  // The first one should be gone, and the second one should be at [0].
106  size_t match_count;
107  EXPECT_FALSE(results.MatchesForURL(url1, NULL));
108  const size_t* matches = results.MatchesForURL(url2, &match_count);
109  ASSERT_EQ(1U, match_count);
110  EXPECT_TRUE(matches[0] == 0);
111
112  // Delete the second URL, there should be nothing left.
113  results.DeleteURL(url2);
114  EXPECT_EQ(0U, results.size());
115  EXPECT_FALSE(results.MatchesForURL(url2, NULL));
116}
117
118}  // namespace history
119