Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 <string> | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/file_path.h" | |
| 9 #include "base/logging.h" | |
| 10 #include "base/stl_util.h" | |
| 11 #include "content/browser/download/download_query.h" | |
| 12 #include "content/browser/download/mock_download_item.h" | |
| 13 #include "testing/gmock/include/gmock/gmock.h" | |
| 14 #include "testing/gtest/include/gtest/gtest.h" | |
| 15 | |
| 16 #include "base/utf_string_conversions.h" | |
| 17 | |
| 18 using ::testing::_; | |
| 19 using ::testing::Return; | |
| 20 using ::testing::ReturnRef; | |
| 21 typedef DownloadQuery::DownloadVector DownloadVector; | |
| 22 | |
| 23 class DownloadQueryTest : public testing::Test { | |
| 24 public: | |
| 25 DownloadQueryTest() {} | |
| 26 virtual ~DownloadQueryTest() {} | |
| 27 virtual void TearDown() { | |
| 28 STLDeleteElements(&mocks_); | |
| 29 } | |
| 30 void CreateMocks(int count) { | |
| 31 for (int i = 0; i < count; ++i) { | |
| 32 MockDownloadItem* mock = new MockDownloadItem(); | |
| 33 mocks_.push_back(mock); | |
| 34 all_items_.push_back(mock); | |
| 35 } | |
| 36 } | |
| 37 MockDownloadItem& mock(int index) { return *mocks_[index]; } | |
| 38 DownloadQuery* query() { return &query_; } | |
| 39 DownloadVector* all_items() { return &all_items_; } | |
| 40 DownloadVector* results() { return &results_; } | |
| 41 void Search() { | |
| 42 results_.clear(); | |
| 43 query()->Search(all_items_.begin(), all_items_.end(), &results_); | |
| 44 } | |
| 45 | |
| 46 private: | |
| 47 std::vector<MockDownloadItem*> mocks_; | |
| 48 DownloadQuery query_; | |
| 49 DownloadVector all_items_; | |
|
Randy Smith (Not in Mondays)
2011/12/05 20:25:42
Why have all_items_ separate from mocks_? It's no
benjhayden
2011/12/09 19:29:15
I didn't want to do that because it would require
| |
| 50 DownloadVector results_; | |
| 51 | |
| 52 DISALLOW_COPY_AND_ASSIGN(DownloadQueryTest); | |
| 53 }; | |
| 54 | |
| 55 #define MOCK(_index, _method, _value) \ | |
| 56 EXPECT_CALL(mock(_index), _method).WillRepeatedly(_value) | |
|
Randy Smith (Not in Mondays)
2011/12/05 20:25:42
nit, suggestion: My personal reaction to this is t
benjhayden
2011/12/09 19:29:15
Done.
| |
| 57 | |
| 58 TEST_F(DownloadQueryTest, EmptyQueryNoItems) { | |
| 59 Search(); | |
| 60 EXPECT_EQ(0U, results()->size()); | |
| 61 } | |
| 62 | |
| 63 TEST_F(DownloadQueryTest, EmptyQuerySomeItems) { | |
| 64 CreateMocks(3); | |
| 65 Search(); | |
| 66 EXPECT_EQ(3U, results()->size()); | |
| 67 } | |
| 68 | |
| 69 TEST_F(DownloadQueryTest, InvalidFilters) { | |
| 70 EXPECT_FALSE(query()->Filter(DownloadQuery::FILTER_FIELD_FILENAME_REGEX, | |
| 71 std::string())); | |
| 72 EXPECT_FALSE(query()->Filter(DownloadQuery::FILTER_FIELD_URL_REGEX, | |
| 73 string16())); | |
| 74 DownloadQuery::FilterFieldName kInvalidName = | |
| 75 static_cast<DownloadQuery::FilterFieldName>(kint32max); | |
| 76 EXPECT_FALSE(query()->Filter(kInvalidName, 0)); | |
| 77 EXPECT_FALSE(query()->Filter(kInvalidName, false)); | |
| 78 EXPECT_FALSE(query()->Filter(kInvalidName, std::string())); | |
| 79 EXPECT_FALSE(query()->Filter(kInvalidName, string16())); | |
| 80 EXPECT_FALSE(query()->Filter(kInvalidName, DownloadStateInfo::DANGEROUS_URL)); | |
| 81 EXPECT_FALSE(query()->Filter(kInvalidName, DownloadItem::IN_PROGRESS)); | |
| 82 } | |
| 83 | |
| 84 TEST_F(DownloadQueryTest, Limit) { | |
| 85 CreateMocks(2); | |
| 86 query()->Limit(1); | |
| 87 Search(); | |
| 88 EXPECT_EQ(1U, results()->size()); | |
| 89 } | |
| 90 | |
| 91 // Test the GT/LT filters separately to check that I didn't get them backwards. | |
| 92 TEST_F(DownloadQueryTest, StartedBefore) { | |
| 93 CreateMocks(2); | |
| 94 MOCK(0, GetStartTime(), Return(base::Time::FromDoubleT(0.001))); | |
|
Randy Smith (Not in Mondays)
2011/12/05 20:25:42
I get nervous whenever I see code that expects som
benjhayden
2011/12/09 19:29:15
Done.
| |
| 95 MOCK(1, GetStartTime(), Return(base::Time::FromDoubleT(0.002))); | |
| 96 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_STARTED_BEFORE, 2)); | |
| 97 Search(); | |
| 98 EXPECT_EQ(1U, results()->size()); | |
| 99 } | |
| 100 | |
| 101 TEST_F(DownloadQueryTest, StartedAfter) { | |
| 102 CreateMocks(2); | |
| 103 MOCK(0, GetStartTime(), Return(base::Time::FromDoubleT(0.001))); | |
| 104 MOCK(1, GetStartTime(), Return(base::Time::FromDoubleT(0.002))); | |
| 105 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_STARTED_AFTER, 1)); | |
| 106 Search(); | |
| 107 EXPECT_EQ(1U, results()->size()); | |
| 108 } | |
| 109 | |
| 110 TEST_F(DownloadQueryTest, TotalBytesLess) { | |
| 111 CreateMocks(2); | |
| 112 MOCK(0, GetTotalBytes(), Return(1)); | |
| 113 MOCK(1, GetTotalBytes(), Return(2)); | |
| 114 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_TOTAL_BYTES_LESS, 2)); | |
| 115 Search(); | |
| 116 EXPECT_EQ(1U, results()->size()); | |
| 117 } | |
| 118 | |
| 119 TEST_F(DownloadQueryTest, TotalBytesGreater) { | |
| 120 CreateMocks(2); | |
| 121 MOCK(0, GetTotalBytes(), Return(1)); | |
| 122 MOCK(1, GetTotalBytes(), Return(2)); | |
| 123 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_TOTAL_BYTES_GREATER, 1)); | |
| 124 Search(); | |
| 125 EXPECT_EQ(1U, results()->size()); | |
| 126 } | |
| 127 | |
| 128 namespace { | |
| 129 bool IdNotEqual(int not_id, const DownloadItem& item) { | |
|
Randy Smith (Not in Mondays)
2011/12/05 20:25:42
nit: I think Chrome custom is for all helper funct
benjhayden
2011/12/09 19:29:15
Done.
| |
| 130 return item.GetId() != not_id; | |
| 131 } | |
| 132 } | |
| 133 | |
| 134 TEST_F(DownloadQueryTest, AllFilters) { | |
|
Randy Smith (Not in Mondays)
2011/12/05 20:25:42
This is a good test for testing all the filters at
benjhayden
2011/12/09 19:29:15
How does this look now with the EXPECT in a loop?
| |
| 135 // Set up mocks such that only mock(0) matches all filters, and every other | |
| 136 // mock fails a different filter (or two for GREATER/LESS filters). | |
| 137 CreateMocks(14); | |
| 138 FilePath match_filename("match"); | |
| 139 FilePath fail_filename("fail"); | |
| 140 GURL match_url("http://example.com/match"); | |
| 141 GURL fail_url("http://example.com/fail"); | |
| 142 // Picture a 2D matrix. The rows are MockDownloadItems and the columns are | |
| 143 // methods. Every cell contains a value that matches the filters, except for | |
| 144 // the diagonal. Every item matches all the filters except one filter, which | |
| 145 // it fails, except one item, which matches all the filters without exception. | |
| 146 for (size_t i = 0; i < all_items()->size(); ++i) { | |
| 147 MOCK(i, GetId(), Return(i)); | |
|
Randy Smith (Not in Mondays)
2011/12/05 20:25:42
Here is a case where I feel some urge to ask you t
benjhayden
2011/12/09 19:29:15
Done.
| |
| 148 MOCK(i, GetReceivedBytes(), Return((i == 1) ? 2 : 1)); | |
| 149 MOCK(i, GetSafetyState(), Return((i == 2) ? | |
| 150 DownloadItem::DANGEROUS : DownloadItem::DANGEROUS_BUT_VALIDATED)); | |
| 151 MOCK(i, GetFullPath(), ReturnRef( | |
| 152 (i == 3) ? fail_filename : match_filename)); | |
| 153 MOCK(i, GetMimeType(), Return((i == 4) ? "image" : "text")); | |
| 154 MOCK(i, IsPaused(), Return((i == 5) ? false : true)); | |
| 155 MOCK(i, MatchesQuery(_), Return((i == 6) ? false : true)); | |
| 156 MOCK(i, GetStartTime(), Return(base::Time::FromDoubleT( | |
| 157 ((i == 7) ? 1.0 : ((i == 8) ? 3.0 : 2.0)) / 1000.0))); | |
| 158 MOCK(i, GetTotalBytes(), Return((i == 9) ? 1 : ((i == 10) ? 3 : 2))); | |
| 159 MOCK(i, GetOriginalUrl(), ReturnRef((i == 11) ? fail_url : match_url)); | |
| 160 MOCK(i, GetState(), Return((i == 13) ? | |
| 161 DownloadItem::CANCELLED : DownloadItem::IN_PROGRESS)); | |
| 162 MOCK(i, GetDangerType(), Return((i == 14) ? | |
| 163 DownloadStateInfo::DANGEROUS_FILE : DownloadStateInfo::NOT_DANGEROUS)); | |
| 164 } | |
| 165 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_BYTES_RECEIVED, 1)); | |
| 166 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_DANGER_ACCEPTED, true)); | |
| 167 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_FILENAME_REGEX, | |
| 168 string16(ASCIIToUTF16("m")))); | |
| 169 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_FILENAME, | |
| 170 string16(ASCIIToUTF16(match_filename.value())))); | |
| 171 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_MIME, std::string("text"))); | |
| 172 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_PAUSED, true)); | |
| 173 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_QUERY, string16())); | |
| 174 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_STARTED_AFTER, 1)); | |
| 175 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_STARTED_BEFORE, 3)); | |
| 176 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_START_TIME, 2)); | |
| 177 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_TOTAL_BYTES_GREATER, 1)); | |
| 178 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_TOTAL_BYTES_LESS, 3)); | |
| 179 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_TOTAL_BYTES, 2)); | |
| 180 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_URL_REGEX, | |
| 181 std::string("m"))); | |
| 182 CHECK(query()->Filter(DownloadQuery::FILTER_FIELD_URL, match_url.spec())); | |
| 183 query()->Filter(base::Bind(&IdNotEqual, 12)); | |
| 184 query()->Filter(DownloadItem::IN_PROGRESS); | |
| 185 query()->Filter(DownloadStateInfo::NOT_DANGEROUS); | |
| 186 Search(); | |
|
Randy Smith (Not in Mondays)
2011/12/05 20:25:42
Is it possible to search on a query multiple times
benjhayden
2011/12/09 19:29:15
Done.
| |
| 187 EXPECT_EQ(1U, results()->size()); | |
| 188 EXPECT_EQ(0, results()->at(0)->GetId()); | |
| 189 } | |
| 190 | |
| 191 TEST_F(DownloadQueryTest, AllSort) { | |
| 192 // mock br d da fn m p st s tb u id dbh | |
|
Randy Smith (Not in Mondays)
2011/12/05 20:25:42
I think if you're going to have this comment here
benjhayden
2011/12/09 19:29:15
Done.
| |
| 193 // 0 1 0 t a a t 0 1 8 z 1 12 | |
| 194 // 1 1 0 t a a t 0 1 8 z 1 11 | |
| 195 // 2 1 0 t a a t 0 1 8 z 0 10 | |
| 196 // 3 1 0 t a a t 0 1 8 a 0 9 | |
| 197 // 4 1 0 t a a t 0 1 9 a 0 8 | |
| 198 // 5 1 0 t a a t 0 0 9 a 0 7 | |
| 199 // 6 1 0 t a a t 1 0 9 a 0 6 | |
| 200 // 7 1 0 t a a f 1 0 9 a 0 5 | |
| 201 // 8 1 0 t a z f 1 0 9 a 0 4 | |
| 202 // 9 1 0 t z z f 1 0 9 a 0 3 | |
| 203 // 10 1 0 f z z f 1 0 9 a 0 2 | |
| 204 // 11 1 1 f z z f 1 0 9 a 0 1 | |
| 205 // 12 0 1 f z z f 1 0 9 a 0 0 | |
| 206 // dbh mock br d da fn m p st s tb u id dbh | |
| 207 // 0 12 0 1 f z z f 1 0 9 a 0 0 | |
| 208 // 1 11 1 1 f z z f 1 0 9 a 0 1 | |
| 209 // 2 10 1 0 f z z f 1 0 9 a 0 2 | |
| 210 // 3 9 1 0 t z z f 1 0 9 a 0 3 | |
| 211 // 4 8 1 0 t a z f 1 0 9 a 0 4 | |
| 212 // 5 7 1 0 t a a f 1 0 9 a 0 5 | |
| 213 // 6 6 1 0 t a a t 1 0 9 a 0 6 | |
| 214 // 7 5 1 0 t a a t 0 0 9 a 0 7 | |
| 215 // 8 4 1 0 t a a t 0 1 9 a 0 8 | |
| 216 // 9 3 1 0 t a a t 0 1 8 a 0 9 | |
| 217 // 10 2 1 0 t a a t 0 1 8 z 0 10 | |
| 218 // 11 1 1 0 t a a t 0 1 8 z 1 11 | |
| 219 // 12 0 1 0 t a a t 0 1 8 z 1 12 | |
| 220 CreateMocks(13); | |
| 221 FilePath a_filename("a"); | |
| 222 FilePath z_filename("z"); | |
| 223 GURL a_url("http://example.com/a"); | |
| 224 GURL z_url("http://example.com/z"); | |
| 225 for (size_t i = 0; i < all_items()->size(); ++i) { | |
| 226 MOCK(i, GetReceivedBytes(), Return((i >= 12) ? 0 : 1)); | |
| 227 MOCK(i, GetDangerType(), Return((i >= 11) ? | |
| 228 DownloadStateInfo::DANGEROUS_FILE : DownloadStateInfo::NOT_DANGEROUS)); | |
| 229 MOCK(i, GetSafetyState(), Return((i >= 10) ? | |
| 230 DownloadItem::DANGEROUS : DownloadItem::DANGEROUS_BUT_VALIDATED)); | |
| 231 MOCK(i, GetFullPath(), ReturnRef((i >= 9) ? z_filename : a_filename)); | |
| 232 MOCK(i, GetMimeType(), Return((i >= 8) ? "z" : "a")); | |
| 233 MOCK(i, IsPaused(), Return((i >= 7) ? false : true)); | |
| 234 MOCK(i, GetStartTime(), Return(base::Time::FromDoubleT( | |
| 235 ((i >= 6) ? 2.0 : 1.0) / 1000.0))); | |
| 236 MOCK(i, GetState(), Return( | |
| 237 (i >= 5) ? DownloadItem::IN_PROGRESS : DownloadItem::COMPLETE)); | |
| 238 MOCK(i, GetTotalBytes(), Return((i >= 4) ? 1 : 0)); | |
| 239 MOCK(i, GetOriginalUrl(), ReturnRef((i >= 3) ? a_url : z_url)); | |
| 240 MOCK(i, GetId(), Return((i >= 2) ? 0 : 1)); | |
| 241 MOCK(i, GetDbHandle(), Return(all_items()->size() - 1 - i)); | |
| 242 // all_items() is in exactly the wrong order. | |
| 243 } | |
| 244 query()->Sort(DownloadQuery::SORT_FIELD_BYTES_RECEIVED, | |
| 245 DownloadQuery::ASCENDING); | |
| 246 query()->Sort(DownloadQuery::SORT_FIELD_DANGER, DownloadQuery::DESCENDING); | |
| 247 query()->Sort(DownloadQuery::SORT_FIELD_DANGER_ACCEPTED, | |
| 248 DownloadQuery::ASCENDING); | |
| 249 query()->Sort(DownloadQuery::SORT_FIELD_FILENAME, DownloadQuery::DESCENDING); | |
| 250 query()->Sort(DownloadQuery::SORT_FIELD_MIME, DownloadQuery::DESCENDING); | |
| 251 query()->Sort(DownloadQuery::SORT_FIELD_PAUSED, DownloadQuery::ASCENDING); | |
| 252 query()->Sort(DownloadQuery::SORT_FIELD_START_TIME, | |
| 253 DownloadQuery::DESCENDING); | |
| 254 query()->Sort(DownloadQuery::SORT_FIELD_STATE, DownloadQuery::ASCENDING); | |
| 255 query()->Sort(DownloadQuery::SORT_FIELD_TOTAL_BYTES, | |
| 256 DownloadQuery::DESCENDING); | |
| 257 query()->Sort(DownloadQuery::SORT_FIELD_URL, DownloadQuery::ASCENDING); | |
| 258 Search(); | |
| 259 EXPECT_EQ(13U, results()->size()); | |
| 260 for (int64 i = 0; i < static_cast<int64>(results()->size()); ++i) { | |
| 261 EXPECT_EQ(i, results()->at(i)->GetDbHandle()); | |
| 262 } | |
| 263 } | |
| OLD | NEW |