blob: 41c2f4e31b04e52a6e9b2408fca0ea223d4f3f4d [file] [log] [blame]
[email protected]33d22102012-01-25 17:46:531// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]be052212011-12-14 18:40:402// 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/memory/scoped_ptr.h"
11#include "base/stl_util.h"
12#include "base/string16.h"
13#include "base/time.h"
14#include "base/values.h"
[email protected]0a2bafc2012-02-01 22:35:0015#include "chrome/browser/download/download_query.h"
[email protected]b7d000b2012-06-02 22:18:2116#include "content/public/test/mock_download_item.h"
[email protected]be052212011-12-14 18:40:4017#include "testing/gmock/include/gmock/gmock.h"
18#include "testing/gtest/include/gtest/gtest.h"
19
20using ::testing::Return;
21using ::testing::ReturnRef;
22using ::testing::_;
23using base::Time;
24using base::Value;
[email protected]e582fdd2011-12-20 16:48:1725using content::DownloadItem;
[email protected]be052212011-12-14 18:40:4026typedef DownloadQuery::DownloadVector DownloadVector;
27
28namespace {
29
30bool IdNotEqual(int not_id, const DownloadItem& item) {
31 return item.GetId() != not_id;
32}
33
34bool AlwaysReturn(bool result, const DownloadItem& item) {
35 return result;
36}
37
38} // anonymous namespace
39
40class DownloadQueryTest : public testing::Test {
41 public:
42 DownloadQueryTest() {}
43
44 virtual ~DownloadQueryTest() {}
45
46 virtual void TearDown() {
47 STLDeleteElements(&mocks_);
48 }
49
50 void CreateMocks(int count) {
51 for (int i = 0; i < count; ++i) {
[email protected]75e51b52012-02-04 16:57:5452 mocks_.push_back(new content::MockDownloadItem());
[email protected]be052212011-12-14 18:40:4053 }
54 }
55
[email protected]75e51b52012-02-04 16:57:5456 content::MockDownloadItem& mock(int index) { return *mocks_[index]; }
[email protected]be052212011-12-14 18:40:4057
58 DownloadQuery* query() { return &query_; }
59
60 template<typename ValueType> void AddFilter(
61 DownloadQuery::FilterType name, ValueType value);
62
63 void Search() {
64 query_.Search(mocks_.begin(), mocks_.end(), &results_);
65 }
66
67 DownloadVector* results() { return &results_; }
68
69 private:
[email protected]75e51b52012-02-04 16:57:5470 std::vector<content::MockDownloadItem*> mocks_;
[email protected]be052212011-12-14 18:40:4071 DownloadQuery query_;
72 DownloadVector results_;
73
74 DISALLOW_COPY_AND_ASSIGN(DownloadQueryTest);
75};
76
77template<> void DownloadQueryTest::AddFilter(
78 DownloadQuery::FilterType name, bool cpp_value) {
79 scoped_ptr<base::Value> value(Value::CreateBooleanValue(cpp_value));
80 CHECK(query_.AddFilter(name, *value.get()));
81}
82
83template<> void DownloadQueryTest::AddFilter(
84 DownloadQuery::FilterType name, int cpp_value) {
85 scoped_ptr<base::Value> value(Value::CreateIntegerValue(cpp_value));
86 CHECK(query_.AddFilter(name, *value.get()));
87}
88
89template<> void DownloadQueryTest::AddFilter(
90 DownloadQuery::FilterType name, const char* cpp_value) {
91 scoped_ptr<base::Value> value(Value::CreateStringValue(cpp_value));
92 CHECK(query_.AddFilter(name, *value.get()));
93}
94
95template<> void DownloadQueryTest::AddFilter(
[email protected]d5e60e192013-01-04 00:09:5096 DownloadQuery::FilterType name, std::string cpp_value) {
97 scoped_ptr<base::Value> value(Value::CreateStringValue(cpp_value));
98 CHECK(query_.AddFilter(name, *value.get()));
99}
100
101template<> void DownloadQueryTest::AddFilter(
[email protected]be052212011-12-14 18:40:40102 DownloadQuery::FilterType name, const char16* cpp_value) {
103 scoped_ptr<base::Value> value(Value::CreateStringValue(string16(cpp_value)));
104 CHECK(query_.AddFilter(name, *value.get()));
105}
106
107TEST_F(DownloadQueryTest, DownloadQueryEmptyNoItems) {
108 Search();
109 EXPECT_EQ(0U, results()->size());
110}
111
112TEST_F(DownloadQueryTest, DownloadQueryEmptySomeItems) {
113 CreateMocks(3);
114 Search();
115 EXPECT_EQ(3U, results()->size());
116}
117
118TEST_F(DownloadQueryTest, DownloadQueryInvalidFilters) {
119 scoped_ptr<base::Value> value(Value::CreateIntegerValue(0));
120 EXPECT_FALSE(query()->AddFilter(
121 static_cast<DownloadQuery::FilterType>(kint32max),
122 *value.get()));
123}
124
125TEST_F(DownloadQueryTest, DownloadQueryLimit) {
126 CreateMocks(2);
127 query()->Limit(1);
128 Search();
129 EXPECT_EQ(1U, results()->size());
130}
131
132// Syntactic sugar for an expression version of the switch-case statement.
133// Cf. Lisp's |case| form.
134#define SWITCH2(_index, _col1, _ret1, _default) \
135 ((_index == (_col1)) ? _ret1 : _default)
136#define SWITCH3(_index, _col1, _ret1, _col2, _ret2, _default) \
137 SWITCH2(_index, _col1, _ret1, SWITCH2(_index, _col2, _ret2, _default))
138#define SWITCH4(_index, _col1, _ret1, _col2, _ret2, _col3, _ret3, _default) \
139 SWITCH3(_index, _col1, _ret1, _col2, _ret2, \
140 SWITCH2(_index, _col3, _ret3, _default))
141
[email protected]9dccd8062012-09-17 17:19:12142TEST_F(DownloadQueryTest, DownloadQuery_QueryFilter) {
143 FilePath match_filename(FILE_PATH_LITERAL("query"));
144 FilePath fail_filename(FILE_PATH_LITERAL("fail"));
145 GURL fail_url("http://example.com/fail");
146 GURL match_url("http://query.com/query");
147 scoped_ptr<base::Value> query_str(base::Value::CreateStringValue("query"));
148 static const size_t kNumItems = 4;
149 CreateMocks(kNumItems);
150 for (size_t i = 0; i < kNumItems; ++i) {
151 if (i != 0)
152 EXPECT_CALL(mock(i), GetId()).WillOnce(Return(i));
153 EXPECT_CALL(mock(i), GetTargetFilePath())
154 .WillRepeatedly(ReturnRef((i & 1) ? match_filename : fail_filename));
155 EXPECT_CALL(mock(i), GetOriginalUrl())
156 .WillRepeatedly(ReturnRef((i & 2) ? match_url : fail_url));
157 EXPECT_CALL(mock(i), GetBrowserContext()).WillRepeatedly(Return(
158 static_cast<content::BrowserContext*>(NULL)));
159 }
160 query()->AddFilter(DownloadQuery::FILTER_QUERY, *query_str.get());
161 Search();
162 ASSERT_EQ(3U, results()->size());
163 EXPECT_EQ(1, results()->at(0)->GetId());
164 EXPECT_EQ(2, results()->at(1)->GetId());
165 EXPECT_EQ(3, results()->at(2)->GetId());
166
167 // TODO(phajdan.jr): Also test these strings:
168 // "/\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xbd\xa0\xe5\xa5\xbd",
169 // L"/\x4f60\x597d\x4f60\x597d",
170 // "/%E4%BD%A0%E5%A5%BD%E4%BD%A0%E5%A5%BD"
171}
172
[email protected]be052212011-12-14 18:40:40173TEST_F(DownloadQueryTest, DownloadQueryAllFilters) {
174 // Set up mocks such that only mock(0) matches all filters, and every other
175 // mock fails a different filter (or two for GREATER/LESS filters).
[email protected]9dccd8062012-09-17 17:19:12176 static const size_t kNumItems = 18;
[email protected]d5e60e192013-01-04 00:09:50177 static const int kSomeKnownTime = 1355864196;
178 std::string kSomeKnownTime8601 = "2012-12-18T20:56:";
179 std::string k8601Suffix = ".000Z";
[email protected]be052212011-12-14 18:40:40180 CreateMocks(kNumItems);
181 FilePath refail_filename(FILE_PATH_LITERAL("z"));
182 FilePath fail_filename(FILE_PATH_LITERAL("fail"));
183 FilePath match_filename(FILE_PATH_LITERAL("match"));
184 GURL refail_url("http://z.com/");
185 GURL fail_url("http://example.com/fail");
186 GURL match_url("http://example.com/match");
187 // Picture a 2D matrix. The rows are MockDownloadItems and the columns are
188 // filter types. Every cell contains a value that matches all filters, except
189 // for the diagonal. Every item matches all the filters except one filter,
190 // which it fails, except one item, which matches all the filters without
191 // exception. Each mocked method is used to test (corresponds to) one or more
192 // filter types (columns). For example, GetTotalBytes() is used to test
193 // FILTER_TOTAL_BYTES_GREATER, FILTER_TOTAL_BYTES_LESS, and
194 // FILTER_TOTAL_BYTES, so it uses 3 columns: it returns 1 for row (item) 11,
195 // it returns 4 for row 12, 3 for 13, and it returns 2 for all other rows
196 // (items).
197 for (size_t i = 0; i < kNumItems; ++i) {
198 EXPECT_CALL(mock(i), GetId()).WillRepeatedly(Return(i));
199 EXPECT_CALL(mock(i), GetReceivedBytes()).WillRepeatedly(Return(SWITCH2(i,
200 1, 2,
201 1)));
202 EXPECT_CALL(mock(i), GetSafetyState()).WillRepeatedly(Return(SWITCH2(i,
203 2, DownloadItem::DANGEROUS,
204 DownloadItem::DANGEROUS_BUT_VALIDATED)));
[email protected]9dccd8062012-09-17 17:19:12205 EXPECT_CALL(mock(i), GetTargetFilePath())
206 .WillRepeatedly(ReturnRef(SWITCH3(i,
[email protected]be052212011-12-14 18:40:40207 3, refail_filename,
208 4, fail_filename,
209 match_filename)));
210 EXPECT_CALL(mock(i), GetMimeType()).WillRepeatedly(Return(SWITCH2(i,
211 5, "image",
212 "text")));
213 EXPECT_CALL(mock(i), IsPaused()).WillRepeatedly(Return(SWITCH2(i,
214 6, false,
215 true)));
[email protected]be052212011-12-14 18:40:40216 EXPECT_CALL(mock(i), GetStartTime()).WillRepeatedly(Return(SWITCH4(i,
[email protected]d5e60e192013-01-04 00:09:50217 7, base::Time::FromTimeT(kSomeKnownTime + 1),
218 8, base::Time::FromTimeT(kSomeKnownTime + 4),
219 9, base::Time::FromTimeT(kSomeKnownTime + 3),
220 base::Time::FromTimeT(kSomeKnownTime + 2))));
221 EXPECT_CALL(mock(i), GetEndTime()).WillRepeatedly(Return(SWITCH4(i,
222 10, base::Time::FromTimeT(kSomeKnownTime + 1),
223 11, base::Time::FromTimeT(kSomeKnownTime + 4),
224 12, base::Time::FromTimeT(kSomeKnownTime + 3),
225 base::Time::FromTimeT(kSomeKnownTime + 2))));
[email protected]be052212011-12-14 18:40:40226 EXPECT_CALL(mock(i), GetTotalBytes()).WillRepeatedly(Return(SWITCH4(i,
[email protected]d5e60e192013-01-04 00:09:50227 13, 1,
228 14, 4,
229 15, 3,
[email protected]be052212011-12-14 18:40:40230 2)));
231 EXPECT_CALL(mock(i), GetOriginalUrl()).WillRepeatedly(ReturnRef(SWITCH3(i,
[email protected]d5e60e192013-01-04 00:09:50232 16, refail_url,
233 17, fail_url,
[email protected]be052212011-12-14 18:40:40234 match_url)));
[email protected]9dccd8062012-09-17 17:19:12235 // 15 is AddFilter(Bind(IdNotEqual, 15))
[email protected]be052212011-12-14 18:40:40236 EXPECT_CALL(mock(i), GetState()).WillRepeatedly(Return(SWITCH2(i,
[email protected]d5e60e192013-01-04 00:09:50237 18, DownloadItem::CANCELLED,
[email protected]be052212011-12-14 18:40:40238 DownloadItem::IN_PROGRESS)));
239 EXPECT_CALL(mock(i), GetDangerType()).WillRepeatedly(Return(SWITCH2(i,
[email protected]d5e60e192013-01-04 00:09:50240 19, content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
[email protected]a62d42902012-01-24 17:24:38241 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)));
[email protected]be052212011-12-14 18:40:40242 }
243 for (size_t i = 0; i < kNumItems; ++i) {
244 switch (i) {
245 case 0: break;
246 case 1: AddFilter(DownloadQuery::FILTER_BYTES_RECEIVED, 1); break;
247 case 2: AddFilter(DownloadQuery::FILTER_DANGER_ACCEPTED, true);
248 break;
249 case 3: AddFilter(DownloadQuery::FILTER_FILENAME_REGEX, "a"); break;
250 case 4: AddFilter(DownloadQuery::FILTER_FILENAME,
251 match_filename.value().c_str()); break;
252 case 5: AddFilter(DownloadQuery::FILTER_MIME, "text"); break;
253 case 6: AddFilter(DownloadQuery::FILTER_PAUSED, true); break;
[email protected]d5e60e192013-01-04 00:09:50254 case 7: AddFilter(DownloadQuery::FILTER_STARTED_AFTER,
255 kSomeKnownTime8601 + "37" + k8601Suffix);
[email protected]be052212011-12-14 18:40:40256 break;
[email protected]d5e60e192013-01-04 00:09:50257 case 8: AddFilter(DownloadQuery::FILTER_STARTED_BEFORE,
258 kSomeKnownTime8601 + "40" + k8601Suffix);
259 break;
260 case 9: AddFilter(DownloadQuery::FILTER_START_TIME,
261 kSomeKnownTime8601 + "38" + k8601Suffix);
262 break;
263 case 10: AddFilter(DownloadQuery::FILTER_ENDED_AFTER,
264 kSomeKnownTime8601 + "37" + k8601Suffix);
[email protected]be052212011-12-14 18:40:40265 break;
[email protected]d5e60e192013-01-04 00:09:50266 case 11: AddFilter(DownloadQuery::FILTER_ENDED_BEFORE,
267 kSomeKnownTime8601 + "40" + k8601Suffix);
[email protected]be052212011-12-14 18:40:40268 break;
[email protected]d5e60e192013-01-04 00:09:50269 case 12: AddFilter(DownloadQuery::FILTER_END_TIME,
270 kSomeKnownTime8601 + "38" + k8601Suffix);
[email protected]be052212011-12-14 18:40:40271 break;
[email protected]d5e60e192013-01-04 00:09:50272 case 13: AddFilter(DownloadQuery::FILTER_TOTAL_BYTES_GREATER, 1);
273 break;
274 case 14: AddFilter(DownloadQuery::FILTER_TOTAL_BYTES_LESS, 4);
275 break;
276 case 15: AddFilter(DownloadQuery::FILTER_TOTAL_BYTES, 2); break;
277 case 16: AddFilter(DownloadQuery::FILTER_URL_REGEX, "example");
278 break;
279 case 17: AddFilter(DownloadQuery::FILTER_URL,
[email protected]be052212011-12-14 18:40:40280 match_url.spec().c_str()); break;
[email protected]d5e60e192013-01-04 00:09:50281 case 18: CHECK(query()->AddFilter(base::Bind(&IdNotEqual, 15))); break;
282 case 19: query()->AddFilter(DownloadItem::IN_PROGRESS); break;
283 case 20: query()->AddFilter(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
[email protected]a62d42902012-01-24 17:24:38284 break;
[email protected]be052212011-12-14 18:40:40285 default: NOTREACHED(); break;
286 }
287 Search();
288 ASSERT_EQ(kNumItems - i, results()->size())
289 << "Failing filter: " << i;
290 if (i > 0) {
291 ASSERT_EQ(0, results()->at(0)->GetId())
292 << "Failing filter: " << i;
293 for (size_t j = 1; j < kNumItems - i; ++j) {
294 ASSERT_EQ(static_cast<int32>(j + i), results()->at(j)->GetId())
295 << "Failing filter: " << i;
296 }
297 }
298 }
299}
300
301TEST_F(DownloadQueryTest, DownloadQuerySortBytesReceived) {
302 CreateMocks(2);
303 EXPECT_CALL(mock(0), GetReceivedBytes()).WillRepeatedly(Return(0));
304 EXPECT_CALL(mock(1), GetReceivedBytes()).WillRepeatedly(Return(1));
305 query()->AddSorter(
306 DownloadQuery::SORT_BYTES_RECEIVED, DownloadQuery::DESCENDING);
307 Search();
308 EXPECT_EQ(1, results()->at(0)->GetReceivedBytes());
309 EXPECT_EQ(0, results()->at(1)->GetReceivedBytes());
310}
311
312TEST_F(DownloadQueryTest, DownloadQuerySortDanger) {
313 CreateMocks(2);
314 EXPECT_CALL(mock(0), GetDangerType()).WillRepeatedly(Return(
[email protected]a62d42902012-01-24 17:24:38315 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE));
[email protected]be052212011-12-14 18:40:40316 EXPECT_CALL(mock(1), GetDangerType()).WillRepeatedly(Return(
[email protected]a62d42902012-01-24 17:24:38317 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
[email protected]be052212011-12-14 18:40:40318 query()->AddSorter(
319 DownloadQuery::SORT_DANGER, DownloadQuery::ASCENDING);
320 Search();
[email protected]a62d42902012-01-24 17:24:38321 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
[email protected]be052212011-12-14 18:40:40322 results()->at(0)->GetDangerType());
[email protected]a62d42902012-01-24 17:24:38323 EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
[email protected]be052212011-12-14 18:40:40324 results()->at(1)->GetDangerType());
325}
326
327TEST_F(DownloadQueryTest, DownloadQuerySortDangerAccepted) {
328 CreateMocks(2);
329 EXPECT_CALL(mock(0), GetSafetyState()).WillRepeatedly(Return(
330 DownloadItem::DANGEROUS));
331 EXPECT_CALL(mock(1), GetSafetyState()).WillRepeatedly(Return(
332 DownloadItem::DANGEROUS_BUT_VALIDATED));
333 query()->AddSorter(
334 DownloadQuery::SORT_DANGER_ACCEPTED, DownloadQuery::DESCENDING);
335 Search();
336 EXPECT_EQ(DownloadItem::DANGEROUS_BUT_VALIDATED,
337 results()->at(0)->GetSafetyState());
338 EXPECT_EQ(DownloadItem::DANGEROUS, results()->at(1)->GetSafetyState());
339}
340
341TEST_F(DownloadQueryTest, DownloadQuerySortFilename) {
342 CreateMocks(2);
[email protected]9dccd8062012-09-17 17:19:12343 FilePath a_path(FILE_PATH_LITERAL("a"));
344 FilePath b_path(FILE_PATH_LITERAL("b"));
345 EXPECT_CALL(mock(0), GetTargetFilePath()).WillRepeatedly(ReturnRef(b_path));
346 EXPECT_CALL(mock(1), GetTargetFilePath()).WillRepeatedly(ReturnRef(a_path));
[email protected]be052212011-12-14 18:40:40347 query()->AddSorter(
348 DownloadQuery::SORT_FILENAME, DownloadQuery::ASCENDING);
349 Search();
[email protected]9dccd8062012-09-17 17:19:12350 EXPECT_EQ(a_path, results()->at(0)->GetTargetFilePath());
351 EXPECT_EQ(b_path, results()->at(1)->GetTargetFilePath());
[email protected]be052212011-12-14 18:40:40352}
353
354TEST_F(DownloadQueryTest, DownloadQuerySortMime) {
355 CreateMocks(2);
356 EXPECT_CALL(mock(0), GetMimeType()).WillRepeatedly(Return("a"));
357 EXPECT_CALL(mock(1), GetMimeType()).WillRepeatedly(Return("b"));
358 query()->AddSorter(
359 DownloadQuery::SORT_MIME, DownloadQuery::DESCENDING);
360 Search();
361 EXPECT_EQ("b", results()->at(0)->GetMimeType());
362 EXPECT_EQ("a", results()->at(1)->GetMimeType());
363}
364
365TEST_F(DownloadQueryTest, DownloadQuerySortPaused) {
366 CreateMocks(2);
367 EXPECT_CALL(mock(0), IsPaused()).WillRepeatedly(Return(true));
368 EXPECT_CALL(mock(1), IsPaused()).WillRepeatedly(Return(false));
369 query()->AddSorter(
370 DownloadQuery::SORT_PAUSED, DownloadQuery::ASCENDING);
371 Search();
[email protected]7610ed72011-12-19 12:28:28372 EXPECT_FALSE(results()->at(0)->IsPaused());
373 EXPECT_TRUE(results()->at(1)->IsPaused());
[email protected]be052212011-12-14 18:40:40374}
375
[email protected]d5e60e192013-01-04 00:09:50376TEST_F(DownloadQueryTest, DownloadQuerySortEndTime) {
377 CreateMocks(2);
378 EXPECT_CALL(mock(0), GetEndTime()).WillRepeatedly(Return(
379 base::Time::FromTimeT(0)));
380 EXPECT_CALL(mock(1), GetEndTime()).WillRepeatedly(Return(
381 base::Time::FromTimeT(1)));
382 query()->AddSorter(
383 DownloadQuery::SORT_END_TIME, DownloadQuery::DESCENDING);
384 Search();
385 EXPECT_EQ(base::Time::FromTimeT(1), results()->at(0)->GetEndTime());
386 EXPECT_EQ(base::Time::FromTimeT(0), results()->at(1)->GetEndTime());
387}
388
[email protected]be052212011-12-14 18:40:40389TEST_F(DownloadQueryTest, DownloadQuerySortStartTime) {
390 CreateMocks(2);
391 EXPECT_CALL(mock(0), GetStartTime()).WillRepeatedly(Return(
392 base::Time::FromTimeT(0)));
393 EXPECT_CALL(mock(1), GetStartTime()).WillRepeatedly(Return(
394 base::Time::FromTimeT(1)));
395 query()->AddSorter(
396 DownloadQuery::SORT_START_TIME, DownloadQuery::DESCENDING);
397 Search();
398 EXPECT_EQ(base::Time::FromTimeT(1), results()->at(0)->GetStartTime());
399 EXPECT_EQ(base::Time::FromTimeT(0), results()->at(1)->GetStartTime());
400}
401
402TEST_F(DownloadQueryTest, DownloadQuerySortState) {
403 CreateMocks(2);
404 EXPECT_CALL(mock(0), GetState()).WillRepeatedly(Return(
405 DownloadItem::IN_PROGRESS));
406 EXPECT_CALL(mock(1), GetState()).WillRepeatedly(Return(
407 DownloadItem::COMPLETE));
408 query()->AddSorter(
409 DownloadQuery::SORT_STATE, DownloadQuery::ASCENDING);
410 Search();
411 EXPECT_EQ(DownloadItem::IN_PROGRESS, results()->at(0)->GetState());
412 EXPECT_EQ(DownloadItem::COMPLETE, results()->at(1)->GetState());
413}
414
415TEST_F(DownloadQueryTest, DownloadQuerySortTotalBytes) {
416 CreateMocks(2);
417 EXPECT_CALL(mock(0), GetTotalBytes()).WillRepeatedly(Return(0));
418 EXPECT_CALL(mock(1), GetTotalBytes()).WillRepeatedly(Return(1));
419 query()->AddSorter(
420 DownloadQuery::SORT_TOTAL_BYTES, DownloadQuery::DESCENDING);
421 Search();
422 EXPECT_EQ(1, results()->at(0)->GetTotalBytes());
423 EXPECT_EQ(0, results()->at(1)->GetTotalBytes());
424}
425
426TEST_F(DownloadQueryTest, DownloadQuerySortUrl) {
427 CreateMocks(2);
428 GURL a_url("http://example.com/a");
429 GURL b_url("http://example.com/b");
430 EXPECT_CALL(mock(0), GetOriginalUrl()).WillRepeatedly(ReturnRef(b_url));
431 EXPECT_CALL(mock(1), GetOriginalUrl()).WillRepeatedly(ReturnRef(a_url));
432 query()->AddSorter(
433 DownloadQuery::SORT_URL, DownloadQuery::ASCENDING);
434 Search();
435 EXPECT_EQ(a_url, results()->at(0)->GetOriginalUrl());
436 EXPECT_EQ(b_url, results()->at(1)->GetOriginalUrl());
437}
438
439TEST_F(DownloadQueryTest, DownloadQuerySortId) {
440 CreateMocks(2);
441 EXPECT_CALL(mock(0), GetReceivedBytes()).WillRepeatedly(Return(0));
442 EXPECT_CALL(mock(1), GetReceivedBytes()).WillRepeatedly(Return(0));
443 EXPECT_CALL(mock(0), GetId()).WillRepeatedly(Return(1));
444 EXPECT_CALL(mock(1), GetId()).WillRepeatedly(Return(0));
445 query()->AddSorter(
446 DownloadQuery::SORT_BYTES_RECEIVED, DownloadQuery::DESCENDING);
447 Search();
448 EXPECT_EQ(0, results()->at(0)->GetId());
449 EXPECT_EQ(1, results()->at(1)->GetId());
450}
451
452TEST_F(DownloadQueryTest, DownloadQueryFilterPerformance) {
453 static const int kNumItems = 10000;
454 static const int kNumFilters = 1000;
455 CreateMocks(kNumItems);
456 for (size_t i = 0; i < (kNumFilters - 1); ++i) {
457 query()->AddFilter(base::Bind(&AlwaysReturn, true));
458 }
459 query()->AddFilter(base::Bind(&AlwaysReturn, false));
460 base::Time start = base::Time::Now();
461 Search();
462 base::Time end = base::Time::Now();
463 double nanos = (end - start).InMillisecondsF() * 1000.0 * 1000.0;
464 double nanos_per_item = nanos / static_cast<double>(kNumItems);
465 double nanos_per_item_per_filter = nanos_per_item
466 / static_cast<double>(kNumFilters);
467 std::cout << "Search took " << nanos_per_item_per_filter
468 << " nanoseconds per item per filter.\n";
469}