toolkit/components/places/tests/unit/test_frecency.js

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:128149399d68
1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 /**
8 * Test for bug 406358 to make sure frecency works for empty input/search, but
9 * this also tests for non-empty inputs as well. Because the interactions among
10 * *DIFFERENT* visit counts and visit dates is not well defined, this test
11 * holds one of the two values constant when modifying the other.
12 *
13 * Also test bug 419068 to make sure tagged pages don't necessarily have to be
14 * first in the results.
15 *
16 * Also test bug 426166 to make sure that the results of autocomplete searches
17 * are stable. Note that failures of this test will be intermittent by nature
18 * since we are testing to make sure that the unstable sort algorithm used
19 * by SQLite is not changing the order of the results on us.
20 */
21
22 function AutoCompleteInput(aSearches) {
23 this.searches = aSearches;
24 }
25 AutoCompleteInput.prototype = {
26 constructor: AutoCompleteInput,
27
28 searches: null,
29
30 minResultsForPopup: 0,
31 timeout: 10,
32 searchParam: "",
33 textValue: "",
34 disableAutoComplete: false,
35 completeDefaultIndex: false,
36
37 get searchCount() {
38 return this.searches.length;
39 },
40
41 getSearchAt: function(aIndex) {
42 return this.searches[aIndex];
43 },
44
45 onSearchBegin: function() {},
46 onSearchComplete: function() {},
47
48 popupOpen: false,
49
50 popup: {
51 setSelectedIndex: function(aIndex) {},
52 invalidate: function() {},
53
54 // nsISupports implementation
55 QueryInterface: function(iid) {
56 if (iid.equals(Ci.nsISupports) ||
57 iid.equals(Ci.nsIAutoCompletePopup))
58 return this;
59
60 throw Components.results.NS_ERROR_NO_INTERFACE;
61 }
62 },
63
64 // nsISupports implementation
65 QueryInterface: function(iid) {
66 if (iid.equals(Ci.nsISupports) ||
67 iid.equals(Ci.nsIAutoCompleteInput))
68 return this;
69
70 throw Components.results.NS_ERROR_NO_INTERFACE;
71 }
72 }
73
74 function ensure_results(uris, searchTerm)
75 {
76 promiseAsyncUpdates().then(function () ensure_results_internal(uris,
77 searchTerm));
78 }
79
80 function ensure_results_internal(uris, searchTerm)
81 {
82 var controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
83 getService(Components.interfaces.nsIAutoCompleteController);
84
85 // Make an AutoCompleteInput that uses our searches
86 // and confirms results on search complete
87 var input = new AutoCompleteInput(["history"]);
88
89 controller.input = input;
90
91 var numSearchesStarted = 0;
92 input.onSearchBegin = function() {
93 numSearchesStarted++;
94 do_check_eq(numSearchesStarted, 1);
95 };
96
97 input.onSearchComplete = function() {
98 do_check_eq(numSearchesStarted, 1);
99 do_check_eq(controller.searchStatus,
100 Ci.nsIAutoCompleteController.STATUS_COMPLETE_MATCH);
101 do_check_eq(controller.matchCount, uris.length);
102 for (var i=0; i<controller.matchCount; i++) {
103 do_check_eq(controller.getValueAt(i), uris[i].spec);
104 }
105
106 deferEnsureResults.resolve();
107 };
108
109 controller.startSearch(searchTerm);
110 }
111
112 // Get history service
113 try {
114 var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
115 getService(Ci.nsINavHistoryService);
116 var bhist = histsvc.QueryInterface(Ci.nsIBrowserHistory);
117 var tagssvc = Cc["@mozilla.org/browser/tagging-service;1"].
118 getService(Ci.nsITaggingService);
119 var bmksvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
120 getService(Ci.nsINavBookmarksService);
121 } catch(ex) {
122 do_throw("Could not get history service\n");
123 }
124
125 function task_setCountDate(aURI, aCount, aDate)
126 {
127 // We need visits so that frecency can be computed over multiple visits
128 let visits = [];
129 for (let i = 0; i < aCount; i++) {
130 visits.push({ uri: aURI, visitDate: aDate, transition: TRANSITION_TYPED });
131 }
132 yield promiseAddVisits(visits);
133 }
134
135 function setBookmark(aURI)
136 {
137 bmksvc.insertBookmark(bmksvc.bookmarksMenuFolder, aURI, -1, "bleh");
138 }
139
140 function tagURI(aURI, aTags) {
141 bmksvc.insertBookmark(bmksvc.unfiledBookmarksFolder, aURI,
142 bmksvc.DEFAULT_INDEX, "bleh");
143 tagssvc.tagURI(aURI, aTags);
144 }
145
146 var uri1 = uri("http://site.tld/1");
147 var uri2 = uri("http://site.tld/2");
148 var uri3 = uri("http://aaaaaaaaaa/1");
149 var uri4 = uri("http://aaaaaaaaaa/2");
150
151 // d1 is younger (should show up higher) than d2 (PRTime is in usecs not msec)
152 // Make sure the dates fall into different frecency buckets
153 var d1 = new Date(Date.now() - 1000 * 60 * 60) * 1000;
154 var d2 = new Date(Date.now() - 1000 * 60 * 60 * 24 * 10) * 1000;
155 // c1 is larger (should show up higher) than c2
156 var c1 = 10;
157 var c2 = 1;
158
159 var tests = [
160 // test things without a search term
161 function() {
162 print("TEST-INFO | Test 0: same count, different date");
163 yield task_setCountDate(uri1, c1, d1);
164 yield task_setCountDate(uri2, c1, d2);
165 tagURI(uri1, ["site"]);
166 ensure_results([uri1, uri2], "");
167 },
168 function() {
169 print("TEST-INFO | Test 1: same count, different date");
170 yield task_setCountDate(uri1, c1, d2);
171 yield task_setCountDate(uri2, c1, d1);
172 tagURI(uri1, ["site"]);
173 ensure_results([uri2, uri1], "");
174 },
175 function() {
176 print("TEST-INFO | Test 2: different count, same date");
177 yield task_setCountDate(uri1, c1, d1);
178 yield task_setCountDate(uri2, c2, d1);
179 tagURI(uri1, ["site"]);
180 ensure_results([uri1, uri2], "");
181 },
182 function() {
183 print("TEST-INFO | Test 3: different count, same date");
184 yield task_setCountDate(uri1, c2, d1);
185 yield task_setCountDate(uri2, c1, d1);
186 tagURI(uri1, ["site"]);
187 ensure_results([uri2, uri1], "");
188 },
189
190 // test things with a search term
191 function() {
192 print("TEST-INFO | Test 4: same count, different date");
193 yield task_setCountDate(uri1, c1, d1);
194 yield task_setCountDate(uri2, c1, d2);
195 tagURI(uri1, ["site"]);
196 ensure_results([uri1, uri2], "site");
197 },
198 function() {
199 print("TEST-INFO | Test 5: same count, different date");
200 yield task_setCountDate(uri1, c1, d2);
201 yield task_setCountDate(uri2, c1, d1);
202 tagURI(uri1, ["site"]);
203 ensure_results([uri2, uri1], "site");
204 },
205 function() {
206 print("TEST-INFO | Test 6: different count, same date");
207 yield task_setCountDate(uri1, c1, d1);
208 yield task_setCountDate(uri2, c2, d1);
209 tagURI(uri1, ["site"]);
210 ensure_results([uri1, uri2], "site");
211 },
212 function() {
213 print("TEST-INFO | Test 7: different count, same date");
214 yield task_setCountDate(uri1, c2, d1);
215 yield task_setCountDate(uri2, c1, d1);
216 tagURI(uri1, ["site"]);
217 ensure_results([uri2, uri1], "site");
218 },
219 // There are multiple tests for 8, hence the multiple functions
220 // Bug 426166 section
221 function() {
222 print("TEST-INFO | Test 8.1a: same count, same date");
223 setBookmark(uri3);
224 setBookmark(uri4);
225 ensure_results([uri4, uri3], "a");
226 },
227 function() {
228 print("TEST-INFO | Test 8.1b: same count, same date");
229 setBookmark(uri3);
230 setBookmark(uri4);
231 ensure_results([uri4, uri3], "aa");
232 },
233 function() {
234 print("TEST-INFO | Test 8.2: same count, same date");
235 setBookmark(uri3);
236 setBookmark(uri4);
237 ensure_results([uri4, uri3], "aaa");
238 },
239 function() {
240 print("TEST-INFO | Test 8.3: same count, same date");
241 setBookmark(uri3);
242 setBookmark(uri4);
243 ensure_results([uri4, uri3], "aaaa");
244 },
245 function() {
246 print("TEST-INFO | Test 8.4: same count, same date");
247 setBookmark(uri3);
248 setBookmark(uri4);
249 ensure_results([uri4, uri3], "aaa");
250 },
251 function() {
252 print("TEST-INFO | Test 8.5: same count, same date");
253 setBookmark(uri3);
254 setBookmark(uri4);
255 ensure_results([uri4, uri3], "aa");
256 },
257 function() {
258 print("TEST-INFO | Test 8.6: same count, same date");
259 setBookmark(uri3);
260 setBookmark(uri4);
261 ensure_results([uri4, uri3], "a");
262 }
263 ];
264
265 /**
266 * This deferred object contains a promise that is resolved when the
267 * ensure_results_internal function has finished its execution.
268 */
269 let deferEnsureResults;
270
271 /**
272 * Test adaptive autocomplete
273 */
274 function run_test()
275 {
276 run_next_test();
277 }
278
279 add_task(function test_frecency()
280 {
281 // always search in history + bookmarks, no matter what the default is
282 var prefs = Cc["@mozilla.org/preferences-service;1"].
283 getService(Ci.nsIPrefBranch);
284 prefs.setIntPref("browser.urlbar.search.sources", 3);
285 prefs.setIntPref("browser.urlbar.default.behavior", 0);
286 for (let [, test] in Iterator(tests)) {
287 remove_all_bookmarks();
288 yield promiseClearHistory();
289
290 deferEnsureResults = Promise.defer();
291 yield test();
292 yield deferEnsureResults.promise;
293 }
294 });

mercurial